ぬの部屋(仮)
nu-no-he-ya
  • 1234567
    891011121314
    15161718192021
    22232425262728
    293031    
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
           
      12345
    6789101112
    13141516171819
    20212223242526
    2728293031  
           
    1234567
    891011121314
    15161718192021
    22232425262728
    2930     
           
        123
    45678910
    11121314151617
    18192021222324
    25262728293031
           
     123456
    78910111213
    14151617181920
    21222324252627
    28293031   
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    30      
       1234
    567891011
    12131415161718
    19202122232425
    262728293031 
           
     123456
    78910111213
    14151617181920
    21222324252627
    282930    
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
    31      
         12
    3456789
    10111213141516
    17181920212223
    2425262728  
           
      12345
    6789101112
    13141516171819
    20212223242526
    2728293031  
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    3031     
        123
    45678910
    11121314151617
    18192021222324
    252627282930 
           
     123456
    78910111213
    14151617181920
    21222324252627
    28293031   
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    30      
       1234
    567891011
    12131415161718
    19202122232425
    262728293031 
           
    1234567
    891011121314
    15161718192021
    22232425262728
    293031    
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
           
      12345
    6789101112
    13141516171819
    20212223242526
    2728293031  
           
    1234567
    891011121314
    15161718192021
    22232425262728
    2930     
           
        123
    45678910
    11121314151617
    18192021222324
    25262728293031
           
       1234
    567891011
    12131415161718
    19202122232425
    26272829   
           
    1234567
    891011121314
    15161718192021
    22232425262728
    293031    
           
        123
    45678910
    11121314151617
    18192021222324
    25262728293031
           
      12345
    6789101112
    13141516171819
    20212223242526
    27282930   
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    3031     
        123
    45678910
    11121314151617
    18192021222324
    252627282930 
           
     123456
    78910111213
    14151617181920
    21222324252627
    28293031   
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
    31      
       1234
    567891011
    12131415161718
    19202122232425
    2627282930  
           
    1234567
    891011121314
    15161718192021
    22232425262728
    293031    
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
           
      12345
    6789101112
    13141516171819
    20212223242526
    2728293031  
           
      12345
    6789101112
    13141516171819
    20212223242526
    2728     
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    3031     
       1234
    567891011
    12131415161718
    19202122232425
    262728293031 
           
     123456
    78910111213
    14151617181920
    21222324252627
    282930    
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
    31      
       1234
    567891011
    12131415161718
    19202122232425
    2627282930  
           
    1234567
    891011121314
    15161718192021
    22232425262728
    293031    
           
        123
    45678910
    11121314151617
    18192021222324
    25262728293031
           
      12345
    6789101112
    13141516171819
    20212223242526
    27282930   
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    3031     
        123
    45678910
    11121314151617
    18192021222324
    252627282930 
           
     123456
    78910111213
    14151617181920
    21222324252627
    28293031   
           
     123456
    78910111213
    14151617181920
    21222324252627
    28      
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
    31      
      12345
    6789101112
    13141516171819
    20212223242526
    2728293031  
           
    1234567
    891011121314
    15161718192021
    22232425262728
    2930     
           
        123
    45678910
    11121314151617
    18192021222324
    25262728293031
           
      12345
    6789101112
    13141516171819
    20212223242526
    27282930   
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    3031     
       1234
    567891011
    12131415161718
    19202122232425
    262728293031 
           
     123456
    78910111213
    14151617181920
    21222324252627
    282930    
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
    31      
       1234
    567891011
    12131415161718
    19202122232425
    2627282930  
           
    1234567
    891011121314
    15161718192021
    22232425262728
    293031    
           
    1234567
    891011121314
    15161718192021
    22232425262728
           
           
        123
    45678910
    11121314151617
    18192021222324
    25262728293031
           
     123456
    78910111213
    14151617181920
    21222324252627
    28293031   
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    30      
       1234
    567891011
    12131415161718
    19202122232425
    262728293031 
           
     123456
    78910111213
    14151617181920
    21222324252627
    282930    
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
    31      
      12345
    6789101112
    13141516171819
    20212223242526
    2728293031  
           
    1234567
    891011121314
    15161718192021
    22232425262728
    2930     
           
        123
    45678910
    11121314151617
    18192021222324
    25262728293031
           
      12345
    6789101112
    13141516171819
    20212223242526
    27282930   
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    3031     
         12
    3456789
    10111213141516
    17181920212223
    242526272829 
           
      12345
    6789101112
    13141516171819
    20212223242526
    2728293031  
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    3031     
        123
    45678910
    11121314151617
    18192021222324
    252627282930 
           
     123456
    78910111213
    14151617181920
    21222324252627
    28293031   
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    30      
       1234
    567891011
    12131415161718
    19202122232425
    262728293031 
           
    1234567
    891011121314
    15161718192021
    22232425262728
    293031    
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
           
      12345
    6789101112
    13141516171819
    20212223242526
    2728293031  
           
    1234567
    891011121314
    15161718192021
    22232425262728
    2930     
           
        123
    45678910
    11121314151617
    18192021222324
    25262728293031
           
        123
    45678910
    11121314151617
    18192021222324
    25262728   
           
     123456
    78910111213
    14151617181920
    21222324252627
    28293031   
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
    31      
       1234
    567891011
    12131415161718
    19202122232425
    2627282930  
           
    1234567
    15161718192021
    293031    
           
         12
    3456789
    10111213141516
           
      12345
    6789101112
    13141516171819
    20212223242526
    2728293031  
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    3031     
        123
    45678910
    11121314151617
    18192021222324
    252627282930 
           
     123456
    78910111213
    14151617181920
    21222324252627
    28293031   
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    30      
       1234
    567891011
    12131415161718
    19202122232425
    262728293031 
           
    1234567
    891011121314
    15161718192021
    22232425262728
    293031    
           
        123
    45678910
    11121314151617
    18192021222324
    25262728293031
           
      12345
    6789101112
    13141516171819
    20212223242526
    27282930   
           
        123
    45678910
    11121314151617
    18192021222324
    252627282930 
           
     123456
    78910111213
    14151617181920
    21222324252627
    28293031   
           
       1234
    567891011
    12131415161718
    19202122232425
    2627282930  
           
    1234567
    891011121314
    15161718192021
    22232425262728
    293031    
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
           
      12345
    6789101112
    13141516171819
    20212223242526
    2728293031  
           
      12345
    6789101112
    13141516171819
    20212223242526
    2728     
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    3031     
     123456
    78910111213
    14151617181920
    21222324252627
    282930    
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
    31      
    1234567
    891011121314
    15161718192021
    22232425262728
    293031    
           
        123
    45678910
    11121314151617
    18192021222324
    252627282930 
           
     123456
    78910111213
    14151617181920
    21222324252627
    28293031   
           
     123456
    78910111213
    14151617181920
    21222324252627
    28293031   
           
       1234
    567891011
    12131415161718
    19202122232425
    262728293031 
           
     123456
    78910111213
    14151617181920
    21222324252627
    282930    
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
    31      
      12345
    6789101112
    13141516171819
    20212223242526
    2728293031  
           
    1234567
    891011121314
    15161718192021
    22232425262728
    2930     
           
        123
    45678910
    11121314151617
    18192021222324
    25262728293031
           
      12345
    6789101112
    13141516171819
    20212223242526
    27282930   
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    3031     
          1
    2345678
    9101112131415
    16171819202122
    232425262728 
           
       1234
    567891011
    12131415161718
    19202122232425
    262728293031 
           
    1234567
    891011121314
    15161718192021
    22232425262728
    293031    
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
           
      12345
    6789101112
    13141516171819
    20212223242526
    2728293031  
           
    1234567
    891011121314
    15161718192021
    22232425262728
    2930     
           
        123
    45678910
    11121314151617
    18192021222324
    25262728293031
           
  • VC++でwxWidgetsを試す(1)

    CMake

    Windows用のバイナリもあるのだがなぜかうまくいかない?デバッグ用のdllしか用意されていない?ので自分でCMakeした方がよい。

    拍子抜けするほど簡単。

    installディレクトリだけ気を付ければ詰まらない。ビルドもすぐに終わる。

    VC++での使用例

    VC++から使用するときの設定

    1. プリプロセッサに __WXMSW__ , WXUSINGDLL を追加
    2. サブシステムをWINDOWSに設定
    3. 追加のライブラリディレクトリ
      ・C:\libraries\wxWidgets\release\lib\vc_x64_dll
    4. includeディレクトリ
      ・C:\libraries\wxWidgets\release\include
      ・C:\libraries\wxWidgets\release\lib\vc_x64_dll\mswu
    // https://docs.wxwidgets.org/3.0/overview_helloworld.html
    
    // プリプロセッサに以下二つを追加
    // __WXMSW__
    // WXUSINGDLL
    
    // サブシステムをWindowsに設定(WinMainで呼び出すので)
    // Windows (/SUBSYSTEM:WINDOWS)
    
    #ifndef WX_PRECOMP
    #include <wx/wx.h>
    #endif
    
    #include <wx/gdicmn.h> // wxPointに必要
    #include <wx/frame.h>  // wxFrameに必要
    
    
    #pragma comment(lib,"wxbase32u.lib")
    #pragma comment(lib,"wxbase32u_net.lib")
    #pragma comment(lib,"wxbase32u_xml.lib")
    #pragma comment(lib,"wxmsw32u_adv.lib")
    #pragma comment(lib,"wxmsw32u_aui.lib")
    #pragma comment(lib,"wxmsw32u_core.lib")
    #pragma comment(lib,"wxmsw32u_gl.lib")
    #pragma comment(lib,"wxmsw32u_html.lib")
    #pragma comment(lib,"wxmsw32u_media.lib")
    #pragma comment(lib,"wxmsw32u_propgrid.lib")
    #pragma comment(lib,"wxmsw32u_qa.lib")
    #pragma comment(lib,"wxmsw32u_ribbon.lib")
    #pragma comment(lib,"wxmsw32u_richtext.lib")
    #pragma comment(lib,"wxmsw32u_stc.lib")
    #pragma comment(lib,"wxmsw32u_webview.lib")
    #pragma comment(lib,"wxmsw32u_xrc.lib")
    
    
    
    /////////////////////////////////////
    /////////////////////////////////////
    /////////////////////////////////////
    
    
    // ウィンドウ作成
    class MyFrame : public wxFrame
    {
    public:
        MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size) 
            : wxFrame(NULL, wxID_ANY, title, pos, size)
        {
        }
    
    private:
        
        // イベント処理しないときはこれを入れない
        // wxDECLARE_EVENT_TABLE();
    };
    /////////////////////////////////////
    /////////////////////////////////////
    /////////////////////////////////////
    
    
    // wxWidgetsのアプリケーション作成
    class MyApp : public wxApp {
    public:
    
        virtual bool OnInit() {
            MyFrame* frame = new MyFrame("Hello World", wxPoint(50, 50), wxSize(450, 340));
            frame->Show(true);
            return true;
        }
    
    };
    /////////////////////////////////////
    /////////////////////////////////////
    /////////////////////////////////////
    
    
    // WinMainをマクロで定義
    wxIMPLEMENT_APP(MyApp);
    

    CMakeLists.txtでDebugとReleaseに違う設定を与える

    コンパイルオプションと、ライブラリを切り分け、プリプロセッサの指定を変える方法。

    コンパイルオプションを指定

    set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -g")
    set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3")
    

    ライブラリ

    DebugビルドとReleaseビルドで使用するライブラリを変える。

    set( DEBUG_LIB_PATH C:/libraries/wxWidgets/debug/lib/vc_x64_dll)
    find_library( DEBUG_Lib  NAMES wxbase32ud.lib PATHS ${DEBUG_LIB_PATH})
    
    set( RELEASE_LIB_PATH C:/libraries/wxWidgets/release/lib/vc_x64_dll)
    find_library( RELEASE_Lib  NAMES wxbase32u.lib PATHS ${RELEASE_LIB_PATH})
    
    
    target_link_libraries(${MY_PROJECT_NAME} PRIVATE 
      $<$<CONFIG:Debug>:${DEBUG_Lib}>
      $<$<CONFIG:Release>:${RELEASE_Lib}>
    )
    

    プリプロセッサ

    set( RELEASE_def -D__RELEASE__)
    set( DEBUG_def -D__DEBUG__)
    
    target_compile_definitions(
      ${MY_PROJECT_NAME} PRIVATE 
      $<$<CONFIG:Release>:${RELEASE_def}>
      $<$<CONFIG:Debug>:${DEBUG_def}>
    )
    

    その他

    デフォルトでリリースビルドにする。

    ただしこの設定は、Visual StudioのGUIでslnを開いた場合には反映されない。

    if(NOT CMAKE_BUILD_TYPE)
       set(CMAKE_BUILD_TYPE Release)
    endif()
    

    CMakeLists.txtの書き方(VC++想定)

    基本

    まずは基本。以下で、MySolutionというソリューションを作成できる。””で囲まないことに注意。

    project(MySolution CXX)

    しかし、setで変数を定義して、${}で変数指定する方が一般的らしい。

    例として、以下のディレクトリ構造でCMakeLists.txtを書いてみる。

    D:.
    │
    └─src
            CMakeLists.txt
            function.cpp
            main.cpp
            source.hpp
    
    # CMakeのバージョンを設定 今自分が使っているものを指定している
    # 必須要件なので、数字は小さい方がいい。
    cmake_minimum_required(VERSION 3.25)
    
    #############################################
    #############################################
    
    # ソリューション名を設定
    set(MY_SOLUTION_NAME "MySolution")
    
    #プロジェクト名を設定
    set(MY_PROJECT_NAME "MyProject")
    
    # 出力ファイル名を設定
    set(MY_OUTPUT_NAME "myout")
    
    #############################################
    #############################################
    
    # ソリューションを作成
    # プロジェクト名と使用する言語を設定
    project(${MY_SOLUTION_NAME} CXX)
    
    #############################################
    #############################################
    
    # main.cpp function.cppからプロジェクト作成
    add_executable(${MY_PROJECT_NAME} main.cpp function.cpp)
    
    
    #############################################
    #############################################
    # 出力名を"myout.exe"に設定 set_target_properties(${MY_PROJECT_NAME} PROPERTIES OUTPUT_NAME ${MY_OUTPUT_NAME})

    そのほか、必要な設定の追加

    includeディレクトリ、ライブラリディレクトリ、ライブラリファイルを追加する。add_executableとの順番が重要になる。

    # CMakeのバージョンを設定 今自分が使っているものを指定している
    # 必須要件なので、数字は小さい方がいい。
    cmake_minimum_required(VERSION 3.25)
    
    #############################################
    #############################################
    
    # ソリューション名を設定
    set(MY_SOLUTION_NAME "MySolution")
    
    #プロジェクト名を設定
    set(MY_PROJECT_NAME "MyProject")
    
    # 出力ファイル名を設定
    set(MY_OUTPUT_NAME "myout")
    
    #############################################
    #############################################
    
    # ソリューションを作成
    # プロジェクト名と使用する言語を設定
    project(${MY_SOLUTION_NAME} CXX)
    
    #############################################
    #############################################
    
    # ライブラリディレクトリ追加
    # 注:add_executableの前でなければならない
    link_directories(path/to/library/directory)
    
    
    # プロジェクトを作成
    # out.exeという実行ファイルをmain.cppから作成
    add_executable(${MY_PROJECT_NAME} main.cpp function.cpp)
    
    
    # includeディレクトリ追加
    # 注:add_executableの後でなければいけない
    target_include_directories(${MY_PROJECT_NAME} PRIVATE path/to/include/directory)
    
    # ライブラリ追加
    target_link_libraries(${MY_PROJECT_NAME} mylib1.lib mylib2.lib)
    
    
    #############################################
    #############################################
    
    set_target_properties(${MY_PROJECT_NAME} PROPERTIES OUTPUT_NAME ${MY_OUTPUT_NAME})
    

    OpenFrameworksのprojectGeneratorで作成したプロジェクトを移動すると読み込めなくなる対応

    projectGeneratorで作成したソリューションを(いうまでもないがディレクトリごと)別のパスへ移動すると、エラーとなる。例えば作成したmyTestディレクトリのパスを変える。

    before
    ・D:\myDevelop\of-test\myTest\myTest.sln

    after
    ・D:\myDevelop\of-test\test\myTest\myTest.sln

    前提として、以下のパスにOpenFrameworksを配置している。

    D:\myDevelop\of_v0.11.2_vs2017_release\

     

    先に結論

    .sln、.vcxprojファイルをエディタで直接開き、of_v0.11.2_vs2017_releaseフォルダへのパスを全て相対パスで置換する。今回の例では一階層下がったので、..\を追加する。

    before:

    ..\..\of_v0.11.2_vs2017_release

    after:

    ..\..\..\of_v0.11.2_vs2017_release

    ただし場所によっては/区切りなので、それにも対応しておく。

    before:

    ../../of_v0.11.2_vs2017_release

    after:

    ../../../of_v0.11.2_vs2017_release

    極力絶対パスで指定したい場合

    .slnファイルの修正

    以下、どうしても絶対パスを使いたい場合の注意。

    修正前:

    修正後:

    .vcxprojファイルの修正

    まず、フルパスに置換するために以下を置換する

    before:

    ..\..\of_v0.11.2_vs2017_release

    after:

    D:\myDevelop\of_v0.11.2_vs2017_release

    before:

    ../../of_v0.11.2_vs2017_release

    after:

    D:\myDevelop\of_v0.11.2_vs2017_release

    基本的には全て絶対パスでも動くのだが、<ItemGroup>の部分だけは相対パスでなければならない。

    OpenFrameworksをWindows,VisualC++から使ってみる(1)

    導入は非常に簡単で、ダウンロードするだけ。CMake不要。さらに外部ツールのProjectGenerator(インストール不要)を使ってプロジェクトを作成するので間違いもない。

    導入

    非常に簡単。

    OpenFrameworksの公式サイトへ行き、visual studio(2017-2022)をダウンロード、解凍する。

    https://openframeworks.cc/ja/download/

    2.テスト(ProjectGeneratorなしの場合)

    適当なフォルダへ展開できたら、以下のディレクトリ内にある、emptyExample.slnを開く。

    コピーする場合、of_v0.11.2_vs2017_releaseフォルダごとコピーしなければいけないことに注意

    of_v0.11.2_vs2017_release\apps\myApps\emptyExample\emptyExample.sln

    OpenGLを使ってみる

    ofApp.cppに入っているofApp::draw()の中にOpenGLの描画関数を入れてみる。

    #include "ofApp.h"
    
    //--------------------------------------------------------------
    void ofApp::setup(){
    
    }
    
    //--------------------------------------------------------------
    void ofApp::update(){
    
    }
    
    
    //--------------------------------------------------------------
    void ofApp::draw(){
    	glClearColor(1, 0, 0, 1);
    	glClear(GL_COLOR_BUFFER_BIT);
    	glFlush();
    }
    //--------------------------------------------------------------
    void ofApp::keyPressed(int key){
    
    }
    
    //--------------------------------------------------------------
    void ofApp::keyReleased(int key){
    
    }
    
    

    GUIパーツを使ってみる

    ofApp.h

    #pragma once
    
    #include "ofMain.h"
    
    // of-test\of_v0.11.2_vs2017_release\addons\ofxGui\src
    // GUI部品
    #include <ofxGui.h>
    
    class ofApp : public ofBaseApp{
    
      //  GUI部品 ofxGui.h
      ofxPanel gui;
    
      ofxFloatSlider angle; // スライダー
    
      ofxButton button;     // ボタン
    
      ofxToggle toggle;     // チェックボックス
    
      ofxTextField text;    // テキストボックス
    
      // ボタンのイベントリスナー
      void buttonClicked() {
        cout << "ボタンが押された" << endl;
      }
    
      public:
        void setup();
        void update();
        void draw();
        
        void keyPressed(int key);
        // ...
    };
    

    ofApp.cpp

    #include "ofApp.h"
    
    
    //--------------------------------------------------------------
    void ofApp::setup(){
    
      //  GUI部品の作成・登録
      gui.setup();
      gui.add(angle.setup("angle", 0, 10, 300));        // スライダー作成
      gui.add(button.setup("push", 140, 50));           // ボタン作成
      gui.add(toggle.setup("toggle",false, 140, 30));   // チェックボックス作成
      gui.add(text.setup("text-field", "default text"));// テキスト入力
    
      // ボタンにイベントリスナーを登録
      button.addListener(this, &ofApp::buttonClicked);
    
    }

    //--------------------------------------------------------------
    void ofApp::draw(){
      glClearColor(1, 0, 0, 1);
      glClear(GL_COLOR_BUFFER_BIT);
    
    
      ////////////////////////////////////////////
      // OpenGL 1 で 描画開始
      int width = ofGetWindowWidth();
      int height = ofGetWindowHeight();
      glViewport(0, 0, width, height);
      glOrtho(-1, 1, -1, 1, -1, 1);
    
    
      glMatrixMode(GL_PROJECTION);
      glPushMatrix();
      glLoadIdentity();
    
      glMatrixMode(GL_MODELVIEW);
    
      glPushMatrix();
      glLoadIdentity();
      glRotatef(angle.getParameter().cast<float>().get(), 0, 0, 1);
    
      glBegin(GL_QUADS);
      glColor3d(1, 0, 0);
      glVertex2d(-0.7, -0.7);
      glColor3d(0, 1, 0);
      glVertex2d(-0.7, 0.7);
      glColor3d(0, 0, 1);
      glVertex2d(0.7, 0.7);
      glColor3d(1, 1, 1);
      glVertex2d(0.7, -0.7);
      glEnd();
      
      glPopMatrix();
    
      ////////////////////////////////////////////
      // UIを表示
      glMatrixMode(GL_PROJECTION);
      glPopMatrix();
      gui.draw();
    
    
      glFlush();
    
    
    }
    

    CPPファイルをプロジェクトへ追加

    上記だけだとGUIパーツ関係でリンクエラーになるので各.cppファイルをプロジェクトへ追加する。

    2.ProjectGeneratorを使ってプロジェクトを生成

    調べるとVisual Studioのプラグインを使用する例がたくさん出てくるが、どうも現在はProjectGeneratorという外部ツールでソリューションを作る方式に変わっている気がする。

    以下にProjectGenerator.exeがあるのでそれを起動する。

    of_v0.11.2_vs2017_release\projectGenerator\projectGenerator.exe

    Success!と言われたら出力したソリューションを叩くかOpen in IDEでプロジェクトを開ける。

    あとは最初と同じコードで動く。

    RustでscraperでHTMLクレイピング

    Cargo.toml

    [package]
    name = "htmlgen"
    version = "0.1.0"
    edition = "2021"

    [dependencies]
    # HTMLのscraper
    # html5ever = "0.26.0"
    scraper = "0.15.0"

    サンプルコード

    fn main() {
    
    
        let source:&str = r#"<!DOCTYPE html>
        <html lang="ja">
          <head>
            <title> HTML in the code </title>
          </head>
          <body>
            <div id="mymain">
              <p> first line </p>
              <p> second <br/> line </p>
              <p>
       third
       line
              </p>
              <img src="data.jpg" />
            </div>
            <div id="myfooter">
              <p>copyright</p>
            </div>
          </body>
        </html
        "#;
        //////////////////////////
        // HTMLの解析
        let myparse:scraper::Html = scraper::Html::parse_document(&source);
    
        let selector:scraper::Selector = scraper::Selector::parse("*").unwrap();
    
        let parsed:scraper::ElementRef = myparse.select(&selector).next().unwrap();
    
        println!("*************************");
    
        traverse_element(&parsed,1);
    
    }
    
    
    
    
    /// @brief 解析済みのHTMLを再帰的に走査して内容を表示
    /// @param [in] elementref 解析済みのエレメント
    /// @param [in] depth 再帰の階層
    /// @return なし 
    fn traverse_element(elementref: &scraper::ElementRef, depth: usize) {
    
    
        let indent:String = " ".repeat(depth*3);// 階層に合わせて左側に挿入するスペース
    
        let element:&scraper::node::Element = elementref.value();
        let tag_name:&str = element.name();
    
    
        print!("{}",depth); // 階層の表示
    
        print!("{} {}",indent,tag_name); // タグ名表示
    
        // 属性取得・保存
        for attr in element.attrs(){
            let attr_name =&attr.0.to_string();
            let attr_value =&attr.1.to_string();
            print!(" {} = {}",
                &attr_name,
                &attr_value
            );
    
        }
        println!("");
    
    
        // 子要素を再帰的に辿る
        for child in elementref.children() {
    
            if let Some(child_element) = child.value().as_element() {
                // タグの場合
    
                // 子要素を走査
                let c_elem_ref:scraper::ElementRef = scraper::ElementRef::wrap(child).unwrap();          
                traverse_element(&c_elem_ref, depth + 1);
    
    
            } else if let Some(text) = child.value().as_text() {
                // コンテンツの場合
                let contents:&str = text.trim();
                if !contents.is_empty() {
                    print!("{}",depth);
                    // コンテンツを表示
                    println!("[[[[[[[[[[[[[[[[[[{}]]]]]]]]]]]]]]]]]]]]]", contents);
                }
            }
        }
    
    }
    

    実行結果

    
    1    html lang = ja
    2       head
    3          title
    3[[[[[[[[[[[[[[[[[[HTML in the code]]]]]]]]]]]]]]]]]]]]]
    2       body
    3          div id = mymain
    4             p
    4[[[[[[[[[[[[[[[[[[first line]]]]]]]]]]]]]]]]]]]]]
    4             p
    4[[[[[[[[[[[[[[[[[[second]]]]]]]]]]]]]]]]]]]]]
    5                br
    4[[[[[[[[[[[[[[[[[[line]]]]]]]]]]]]]]]]]]]]]
    4             p
    4[[[[[[[[[[[[[[[[[[third
       line]]]]]]]]]]]]]]]]]]]]]
    4             img src = data.jpg
    3          div id = myfooter
    4             p
    4[[[[[[[[[[[[[[[[[[copyright]]]]]]]]]]]]]]]]]]]]]
    
    

    KotlinでJSoupを使ってスクレイピングしてみる

    IntelliJ IDEAでJSoupを使ってみる。

    全くやったことがないので導入だけのメモになる。

    プログラム

    コードは以下の通り。

    import org.jsoup.Jsoup;
    import org.jsoup.nodes.Document;
    import org.jsoup.nodes.Element;
    
    
    fun main(args: Array<String>) {
    
        val url = "https://suzulang.com/"
        val doc = Jsoup.connect(url).get();
    
        println(doc.title());  // タイトル取得
    
        // divの内容をリストで取得
        val divs = doc.select("div");
        for(div in divs){
    
            // div に子要素があればその内容をループ
            if( div.children().size > 0 ){
    
                // pの一覧を取得
                val paragraphs = div.children().select("p");
                for(p in paragraphs){
    
                    println(p.text()); // pの内容を表示
    
                }
            }
        }
    }
    

    IntelliJでJSoupを導入する方法

    以下からダウンロード

    https://jsoup.org/download

    展開したら、[File]→[Project Structure...]を選択

    Dependenciesの中の+をクリックし、JARs or Directories...を選択

    jsoup-1.15.4.jarファイルへのフルパスを指定。ディレクトリまでしか指定しないとjarファイルが表示されないので入力欄にファイル名まで全部入力するといい。

    PythonでHTML(2)lxml

    lxmlを使うとデータをツリー構造に格納してくれる。

    インストール

    conda install lxml

    使用例(テキストから)

    import lxml.html
    
    
    # HTMLのテキスト
    text = """<html>
    <head><title>タイトル</title>
    <body>
    <p> hello world </p>
    <p> 二行目 </p>
    <div>
    子要素
    </div>
    </body>
    </html>
    
    """
    
    ret = lxml.html.fromstring( text )
    
    for itr in ret: # forでイテレーションする
    
    	print(itr.tag) # タグへアクセス
    		
    	if len(list(itr)): # 子要素があるかどうかはlistの長さを調べる
    	
    		print("{")
    		for i in itr:
    			print(i.tag ,"[" ,  i.text , "]" )
    		print("}")
    
    head
    {
    title [ タイトル ]
    }
    body
    {
    p [ hello world ]
    p [ 二行目 ]
    div [
    子要素
    ]
    }

    URLを指定してインターネットからHTML取得

    lxml.html.parseはURLを渡せるのだが、

    lxml.html.parse('http://www.suzulang.com/')

    どうやらHTTPSに対応していないらしい。

    lxml.html.parse('https://www.suzulang.com/') # 失敗

    urllibでインターネットからデータを取得

    urllib.requestを使ってHTMLを取得し、それをfromstringへ入力する。

    # lxmlはhttpsに対応していない。
    # html.parse( /*ここに入れていいのはhttpのURLだけ*/ )
    # urllib.request.urlopenを使ってhttpsからテキストを取得してそれを入力する
    # from urllib import urlopen # Python2だとurllib2らしい
    import urllib.request
    
    
    urldata = urllib.request.urlopen('https://suzulang.com/')
    
    text = urldata.read()
    print( text )
    

    PythonでHTML(1) HTMLParserを使ってHTMLをパースする

    HTMLParserでHTMLをパースする。

    HTMLParserクラスは、このクラスを継承して使用する。

    HTMLParser.feedを呼び出すと、タグなどが見つかった際にオーバーライドしたhandle_starttagメソッドが呼ばれるので、その度に必要な処理を記述する。

    注意

    公式ドキュメント
    https://docs.python.org/3/library/html.parser.html

    にあるコードだとHTML内に改行が見つかるたびにhandle_dataが呼び出されてしまうので、\n単体が見つかった場合は何もしないように処理を追加。

    from html.parser import HTMLParser
    
    #####################################
    # HTMLのテキスト
    text = """<html>
    <body>
    <p> hello world </p>
    </body>
    </html>
    
    """
    
    
    
    
    #####################################
    #https://docs.python.org/3/library/html.parser.html
    # HTMLParserを継承したMyHTMLParserを作成
    class MyHTMLParser(HTMLParser):
    
        # HTMLParser.feed を呼び出すと、以下の各関数がパース中に呼び出される
    
        def handle_starttag(self, tag, attrs):
            print("Encountered a start tag:", tag)
    
        def handle_endtag(self, tag):
            print("Encountered an end tag :", tag)
    
        def handle_data(self, data):
        
            # タグの後の改行でもhandle_dataが呼び出されてしまうため
            # 改行単体の時はひとまず抜ける
            if data == '\n':
                return
    
            print("Encountered some data  :", data)
    
    
    #####################################
    # パース処理
    
    
    ps = MyHTMLParser() # パーサー作成
    
    ps.feed(text) # パース実行
    

    Rust glutinクレートでOpenGLのウィンドウを開く

    OpenGLのウィンドウ生成。

    Cargo.toml

     

    [package]
    name = "testglutin"
    version = "0.1.0"
    edition = "2021"

    [dependencies]
    glutin = "0.26.0"
    gl="0.14.0"

     

    main.rc

    fn main() {
    
        let event_loop = glutin::event_loop::EventLoop::new();
        let window = glutin::window::WindowBuilder::new().with_title("Rust glutin OpenGL");
        
        
        // GLのコンテキストを作成
        // この gl_context は ContextBuilder<NotCurrent,Window> 型
        let gl_context = glutin::ContextBuilder::new()
            .with_gl(glutin::GlRequest::Specific(glutin::Api::OpenGl, (3, 3)))
            .build_windowed(window, &event_loop)
            .expect("Cannot create context");
        
        // Rustにはシャドーイングがあるので、同じ名前の別変数を同じスコープ内に定義できる。
        // この gl_context は ContextBuilder<PossibleCurrent,Window> 型
        // 以降、gl_currentは以前の型の意味で用いることはできない
        let gl_context = unsafe {
            gl_context
                .make_current()
                .expect("Failed to make context current")
        };

        // OpenGLの各関数を初期化
        // これでgl::Viewportをはじめとする各関数の関数ポインタにアドレスが設定され、呼び出せるようになる。
        gl::load_with(|symbol| gl_context.get_proc_address(symbol) as *const _);
    
        // event_loopを開始する
        event_loop.run(move |event, _, control_flow| {
    
            // Pollを指定するとループが走り続ける
            // Waitを指定するとイベントが発生したときだけループが動く。
            *control_flow = glutin::event_loop::ControlFlow::Wait;
    
    
            match event {
    
                glutin::event::Event::WindowEvent { event, .. } => match event {
    
    
    
                    ////////////////////////////////////////////////////////////////////
                    // ウィンドウを閉じる
                    glutin::event::WindowEvent::CloseRequested => {
                        // ウィンドウが閉じられた場合、event_loopを停止する
                        *control_flow = glutin::event_loop::ControlFlow::Exit;
                    },

                    ////////////////////////////////////////////////////////////////////
                    // ウィンドウのサイズを変更
                    glutin::event::WindowEvent::Resized(new_size) => {
    
                        // ビューポート再設定
                        unsafe {
                            gl::Viewport(0, 0, new_size.width as i32, new_size.height as i32);
                        }
                    },

                    ////////////////////////////////////////////////////////////////////
                    _ => (),
                },
    
    
                _ => (),
            }
    
    
            // 描画
            unsafe {
                gl::Clear(gl::COLOR_BUFFER_BIT);
                gl::ClearColor(0.3, 0.3, 0.5, 1.0);
            }
            // スワップバッファ
            gl_context.swap_buffers().unwrap();
            

        });
    
    
    }