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 が主流なので、知識を流用できてスバラシイ。

はてなブログの RSS フィードをダウンロードしてパースする

はてなブログRSS フィードをダウンロードしてパースするサンプルを書いてみた。 RSS フィードのダウンロードは HttpClient.GetStringAsync で一発。 RSS フィードは所詮 XML なので、パースは LINQ to XML でこれまた一発。

簡単過ぎてわざわざブログに書くまでもないかと思ったけど、 LINQ to XML 使う箇所はうっかり忘れてしまいそうな気がしたので、 外部記憶として書いておくことにした。

using System;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
using System.Xml.Linq;

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

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

            Console.ReadLine();
        }

        static async Task MainAsync()
        {
            var client = new HttpClient();

            var rss = await client.GetStringAsync(
                "https://tnakamura.hatenablog.com/rss");

            var xdoc = XDocument.Parse(rss);

            var items = from a in xdoc.Descendants()
                        where a.Name == "item"
                        let title = from b in a.Descendants()
                                    where b.Name == "title"
                                    select b.Value
                        let link = from c in a.Descendants()
                                   where c.Name == "link"
                                   select c.Value
                        select new Item
                        {
                            Title = title.FirstOrDefault(),
                            Link = link.FirstOrDefault(),
                        };

            foreach (var i in items)
            {
                Console.WriteLine(i.Title);
                Console.WriteLine(i.Link);
                Console.WriteLine();
            }
        }
    }

    public class Item
    {
        public string Title { get; set; }

        public string Link { get; set; }
    }
}

実行結果は下の通り。

f:id:griefworker:20180802164727p:plain

今回選んだのがはてなブログだったというだけで、 URL さえ分かっていれば他の RSS フィードでも同じようにダウンロードしてパースできる。

『ゴールデンゴールド(1)〜(4)』を読んだ

Kindle 版の 1 巻が無料だったのを見つけて、 そういえば「このマンガがすごい!」で紹介されていたなと思い出し、 試しに読んでみたらハマってしまった。 4 巻まで一気に読んでしまった。

どんなマンガかは、Amazon に載っている公式のあらすじを引用。

福の神伝説が残る島・寧島で暮らす中2の少女、早坂琉花。ある日、海辺で見つけた奇妙な置物を持ち帰った彼女は、ある「願い」を込めて、それを山の中の祠に置く。すると、彼女の目の前には、“フクノカミ”によく似た異形が現れた――。幼なじみを繋ぎ止めるため、少女が抱いた小さな願いが、この島を欲望まみれにすることになる。

ジャンルは正直わからない。 ホラーのような気もするけど、違う気もする。

人とお金を吸い寄せるフクノカミの影響を受け、 祖母の町子や幼なじみの及川をはじめ、 島のみんなが次第におかしくなっていく。 お金の魔力に狂わされていったのか、 それともフクノカミに操られているのか。 今のところ両方って感じだ。 町子の顔がたまにフクノカミになったりするし。

フクノカミは不気味だけど、どこか可愛らしさがある。 昔、キモカワイイという言葉があったと記憶しているが、 それにちなんでブキミカワイイとでも言おうか。 どうも琉花の願いを叶えようとしているみたいで、 憎めないところがある。 それが存在意義みたいなものなんだろうけど。

町子たちを正気に戻すために、 島の歴史からフクノカミについて調べたり、 閉じ込めようとしたりするものの、 どれもうまくいかず、 フクノカミの影響はどんどん広がって行く。 フクノカミを狙う人物まで登場し、 この先どうなるのか読めない。 このままいくとバッドエンドになりそうな予感がする。 それだとちょっと救いがないので、 せめて琉花だけでも救われる展開であってほしい。

『星野、目をつぶって。(12)』を読んだ

星野は素顔を晒したせいで今までのグループには入れなくなったけど、小早川と共にジャージ女として活動していて築いた新しい繋がりがあることに気付かされたところはクルものがあった。

新しい繋がりがあるからそれで万事OKとはもちろんいかないわけで、 小早川は星野が元のグループに戻れるように文字通り身体を張る。 本人はカッコ悪いと思うんだろうが、 ブン投げられていても不思議とカッコいい。自分から行動を起こせるようになったからなんだろうな。

余談だけど、加納、 チョコレート作りの腕前もパティシエ級てどんだけ高スペックなのよ。 勉強料理運動なんでもできてマジ完璧超人。 松方と和解した今となっては、欠点といったら男の趣味くらいか。 小早川と星野は復縁という感じではないし、加納にワンチャンあったりしないもんかね。

このマンガはとうとう次巻で完結。 ラブコメを長く引っ張ってもグダるだけなので、13巻くらいで終わるのはちょうどいいかもしれない。

笑うかど

薬院にある『笑うかど』に晩ご飯を食べに行ってきた。ゴールデンウィークに行ったときは運悪く店休日だったので、今回はリベンジ。開いててよかった。

ボリュームありそうなメニューがたくさんあって目移りしそうだった。 その中でも一際目を引いたのが人気メニューの『オムカツそばめし』。こいつに決めた。

ソースでしっかりと味付けされたそばめしに、ふわとろの卵のまろやかさが合わさって、 ちょうどいい塩梅の味に仕上がっていた。 おむそばに卵は間違いないね。 上のトンカツもアツアツかつサクサク。 予想以上のボリュームでお腹はもうパンパンになった。

職場か自宅の近くにこんな定食屋があればなぁ。 薬院は良い店が多くて、住んでいる人が羨ましい。

笑うかど
〒810-0022 福岡県福岡市中央区薬院1-11-3 福一第2ビル2F
3,000円(平均)850円(ランチ平均)

『からかい上手の(元)高木さん(3)』を読んだ

やはり血は争えないのか、娘のちーもからかいに目覚めたようだ。 娘にからかいまくると宣言されたときの、西片くんの表情といったらもう。 ウケる。

でも、ちーはどちらかというと父親似なので、(元)高木さんに勝負を挑んで返り討ちにあったり、からかわれたりする。

(元)高木さんと娘の 2 人にからかわれるのは、さすがに西片くんが可哀想なので、(元)高木さん vs. 西片くんとちーぐらいがちょうどいい。まぁ、2 人がかりでも勝てそうにないけど。

望遠のマーチ

iTunes Store で配信されたので購入。 この曲は妖怪ウォッチワールドのタイアップらしい。軽快なテンポ。のびやかなサビ。 スマホを握って外に繰り出したくなる曲だった。

近年のバンプの曲はタイアップが多い。 露出が増えるのは個人的に喜ばしいことに思う。 アルバムが待ち遠しい。

望遠のマーチ

望遠のマーチ