[C#]WinFormでAngleSharpパッケージによるスクレイピングを行う

カテゴリ: C# | タグ:

VisualStudio+WinFormの環境で、AngleSharpパッケージを利用したWebページのスクレイピングを行ってみます。

AngleSharpを使えるようにする

AngleSharpは、NuGetパッケージとして提供されているので、パッケージのインストールで導入することができます。AngleSharpのパッケージは下記の手順でインストールできます。

プロジェクト->Nugetパッケージの管理を選択します

検索エリアに"AngleSharp"と入力して、結果に表示された"AngleSharp"パッケージをインストールします

プロジェクトの参照設定に"AngleSharp"が追加されていることを確認します

Formのレイアウトを作る

AngleSharpパッケージのインストールができたら、次はFormの画面を作ります。

今回は動作確認のため、以下のようにButtonとTextBoxを1つづつ配置したフォームを用意しました。

AngleSharpのSimpleDemoコードをWinFormから実行する

ボタンをクリックしたときのイベントハンドラを実装します。

getTitles()の中身は、AngleSharpのgithubページ(https://github.com/AngleSharp/AngleSharp)の内容をそのままコピーしています。

また、サンプルのコードは非同期処理で実行されているのでbutton1_Click()メソッドをasyncにしています。

namespace Test {
    public partial class Form1 :Form {
        public Form1() {
            InitializeComponent();
        }

        /** 
         * ボタンクリック時のハンドラ
         */
        private async void button1_Click( object sender, EventArgs e ) {

            var titles = await getTitles();
            foreach (var title in titles ) {
                textBox1.AppendText( title + Environment.NewLine );
            }
        }


        /**
         * The Big Bang Theoryのタイトル一覧をWikipediaから取得する
         */
        private async Task<System.Collections.Generic.IEnumerable<string>> getTitles() {
            // Setup the configuration to support document loading
            var config = Configuration.Default.WithDefaultLoader();

            // Load the names of all The Big Bang Theory episodes from Wikipedia
            var address = "https://en.wikipedia.org/wiki/List_of_The_Big_Bang_Theory_episodes";

            // Asynchronously get the document in a new context using the configuration
            var document = await BrowsingContext.New( config ).OpenAsync( address );

            // This CSS selector gets the desired content
            var cellSelector = "tr.vevent td:nth-child(3)";

            // Perform the query to get all cells with the content
            var cells = document.QuerySelectorAll( cellSelector );

            // We are only interested in the text - select it with LINQ
            var titles = cells.Select( m => m.TextContent );

            return titles;
        }
    }
}

実行結果を確認する

プログラムを実行し、ソースコードの記載のページ(https://en.wikipedia.org/wiki/List_of_The_Big_Bang_Theory_episodes)のタイトル一覧が出力されればOKです。

サンプルコードを少しだけ使いやすくする

せっかく動作確認のアプリケーションを作ったので、少しだけ改善して汎用的に使えるようにしてみます。

FormでURLをセレクタを指定可能に

先ほどの例ではURLとセレクタがプログラム中に記載されていたため、Formから指定できるようにします。

Formから指定された情報で検索を行う

次に、指定されたURLとセレクタを元に検索が行えるようにします。

private async void button1_Click( object sender, EventArgs e ) {
    var url = txtUrl.Text;
    var selector = txtSelector.Text;

    var titles = await getTitles(url, selector);
    foreach (var title in titles ) {
        textBox1.AppendText( title + Environment.NewLine );
    }

}

/**
 * 指定されたURLからスクレイピングを行う
 */
private async Task<System.Collections.Generic.IEnumerable<string>> getTitles(string url, string selector ) {
    // Setup the configuration to support document loading
    var config = Configuration.Default.WithDefaultLoader();

    // Asynchronously get the document in a new context using the configuration
    var document = await BrowsingContext.New( config ).OpenAsync( url );

    // Perform the query to get all cells with the content
    var cells = document.QuerySelectorAll( selector );

    // We are only interested in the text - select it with LINQ
    var titles = cells.Select( m => m.TextContent );

    return titles;
}

この変更で、任意のページからスクレイピングが行えるようになりました。

StackOverflowの記事を検索してみる

例えば、URLとセレクタを以下のように指定するだけで、stackoverflow.comから最近の質問一覧を取得することができるようになります。

URL     https://stackoverflow.com/questions/tagged/c%23
セレクタ div#questions h3

ブラウザで指定したURLを開くと以下のように表示されるので、たしかに質問のタイトル一覧が抽出できていることが分かります。

こちらもおススメ

コメントを残す

メールアドレスが公開されることはありません。