Web スクレイピングではてなブロググループのブログ一覧を取得する

はてなブロググループに登録しているブログの一覧を、 Web スクレイピングで取得するサンプルを書いてみた。 HTML のパースには AngleSharp を使用。

using AngleSharp.Dom.Html;
using AngleSharp.Parser.Html;
using System;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;

namespace CrawlerSample
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.Title = "CrawlerSample";

            MainAsync().GetAwaiter().GetResult();

            Console.WriteLine("Enter で終了します。");
            Console.ReadLine();
        }

        static async Task MainAsync()
        {
            // はてなブロググループの「プログラミング」グループを対象にする。
            var baseUrl = "http://hatenablog.com/g/11696248318754550880/blogs";
            var client = new HttpClient();
            var parser = new HtmlParser();
            var requestUrl = baseUrl;

            // 全ページ取得したら攻撃になってしまうので、
            // 3 ページぶんに留めておく。
            for (var i = 0; i < 3; i++)
            {
                // はてなグループブログ一覧の HTML をダウンロードしてパースする。
                var body = await client.GetStringAsync(requestUrl);
                var document = await parser.ParseAsync(body);

                // ブログ一覧からブログタイトルとリンクを取り出す。
                // はてなブロググループのブログ一覧は class を cllass にタイポしてるので、
                // cllass 属性で検索する。
                var elements = document.QuerySelectorAll("[cllass=blog-list-content] > a");
                var anchors = elements.Cast<IHtmlAnchorElement>();
                foreach (var a in anchors)
                {
                    Console.WriteLine(a.TextContent);
                    Console.WriteLine(a.Href);
                    Console.WriteLine();
                }

                // 次ページへのリンクがあればクロールを続ける。
                // 次ページが無ければ終了。
                var next = document.QuerySelector(".more > a") as IHtmlAnchorElement;
                if (next != null)
                {
                    requestUrl = baseUrl + next.Search; // クエリ文字列の部分を足す
                }
                else
                {
                    break;
                }
            }
        }
    }
}

実行結果は下の通り。

f:id:griefworker:20180803140534p:plain

AngleSharp はセレクタ API が使えるので、目的の要素をサクッと取得できた。 LINQ もいいけど、DOM 操作はセレクタ API が主流なので、知識を流用できてスバラシイ。