[C#] Geckoライブラリを利用してウェブスクレイピングする方法


Devlopment note / C#    作成日付 : 2020/05/05 00:52:26   修正日付 : 2020/05/05 00:55:27

こんにちは。明月です。


この投稿はC#でGeckoライブラリを利用してウェブスクレイピングする方法に関する説明です。


HtmlのレイアウトエンジンとはHtmlドキュメントとCSS Style、Javascriptを画面に描画するレンダリングするエンジンです。

レンダリングエンジンの種類は代表的にMSのIEとMozilla財団のGeckoがあります。IEレンダリングのMSHTMLがありますが、IE 8.0バージョンまではC#で参照して使えます。IEの8.0バージョンはもう10年前のレンダリングエンジンだし、今のスタイルなら様々でエラーが発生するかもしれません。

Geckoレンダリングは60バージョンです。IEより最新バージョンです。


GeckoレイアウトのライブラリはC#のNugetでダウンロード及び連携が可能です。

ブラウザライブラリは一応、WindowのProcメッセージのキューが必要なのでWindow Forms Appでプロジェクトを生成します。


そしてNugetを通ってGeckoライブラリを連携します。



上のイメージをみれば以前45バージョンもあります。45バージョンで作成するなら60バージョンと同じです。ここでは60で作成します。

一応、私のOSは64ビットなので64ビットで作成します。 32ビットも作成方法も同じです。


Windowデザインフォームの隣のtoolbarをみればGecko-browserコントロールができたことを確認できます。


このWindowsフォームにDrap&Dropした後でプロパティのdockをfillに合わせています。


これからFirefox.dllファイルを注入する必要があります。


右Program.csファイルを開いて,下記のソースを追加します。

Xpcom.EnableProfileMonitoring = false;
var app_dir = Path.GetDirectoryName(Application.ExecutablePath);
Xpcom.Initialize(Path.Combine(app_dir, "Firefox64"));


そして右のForm1.csファイルを右クリックしをして、ソースビューでソースを開きます。


using System;
using System.Windows.Forms;
using Gecko;
using Gecko.DOM;
namespace GeckoTest
{
  public partial class Form1 : Form
  {
    bool flag = true;
    public Form1()
    {
      InitializeComponent();
    }
    // FormのOnload関数をオバーライドした。
    protected override void OnLoad(EventArgs e)
    {
      // 親クラスのOnLoad関数を呼び出す。
      base.OnLoad(e);
      // yahooに接続する。
      this.geckoWebBrowser1.Navigate("www.yahoo.co.jp");
      // 接続が完了する時にイベント設定
      this.geckoWebBrowser1.DocumentCompleted += GeckoWebBrowser1_DocumentCompleted;
    }
    // イベント関数
    private void GeckoWebBrowser1_DocumentCompleted(object sender, Gecko.Events.GeckoDocumentCompletedEventArgs e)
    {
      // Geckoブラウザオブジェクトを取得する。
      GeckoWebBrowser browser = (GeckoWebBrowser)sender;
      // URLでyahoo.co.jpの場合
      if (browser.Url.Equals("https://www.yahoo.co.jp/") && flag)
      {
        // 検索画面になったらflagをfalseを変換
        flag = false;
        // document取得する。
        var doc = browser.Document;
        // 検索テキスト
        (doc.GetElementsByName("p")[0] as GeckoInputElement).Value = "site://www.nowonbun.com";
        // 検索ボタンクリック
        (doc.GetElementsByClassName("rapid-noclick-resp")[0] as GeckoButtonElement).Click();
      }
    }
  }
}

上みたいにスクレイピングソースを作成しました。


結果みたいにスクレイピングになったことを確認できます。


-- もしエラーが発生する場合 --

1. 64ビットに設定しても64ビットでできない場合があります。


デバッグ設定をx64に変更すれば解決できます。


デバッグのPropertyメニューを開きます。


メニューのBuildタブでプラットフォームをx64に変更すると解決できます。


2. dllファイルを読み込めませんというエラーメッセージが発生する可能性があります。


この場合はdebugフォルダーが間違って設定されている場合に発生します。

var app_dir = Path.GetDirectoryName(Application.ExecutablePath);	
Xpcom.Initialize(Path.Combine(app_dir, "Firefox64"));

デフォルトならDebugフォルダーのFirefox64のサブフォルダにモジュールがあります。


binのdebugフォルダーに移動すればFirefox64フォルダがあることが確認できます。


ここのフォルダとFirefox64のフォルダ名を一致すると問題なく実行されます。


個人的に最近AfxWebBrowserとWebBrowserよりGeckoBrowserオブジェクトが安定的に使えます。C#の基本WebBrowserオブジェクトはMSIEの8バージョンなので最近のウェブページではScriptエラーが発生する可能性が高いです。


--参考--

ウェブスクレイピング開発のトレンドはGeckoBrowserとHttpWebRequestを混ぜって使います。

でもGeckoBrowserとHttpWebRequestは別のクラスでセッションやクッキー情報の同期化が必要です。

HttpWebRequest request = (HttpWebRequest)WebRequest.Create();
request.Headers["Cookie"] = browser.Document.Cookie;

テストするサイトがないから参考事項で作成しておきました。


ここまでC#でGeckoライブラリを利用してウェブスクレイピングする方法に関する説明でした。


ご不明なところや間違いところがあればコメントしてください。

最新投稿