読者です 読者をやめる 読者になる 読者になる

プログラミングとかブログ

Unity/C#/SRPGStudio/RPGツクールMVの情報とかその他気になったことを調べて書きます。

【C#】ブクログの自分の棚ページをぶち込むと本一覧を書き出すコードを書いた

仕様が変わって文字だけ一覧表示がなくなったので怒りのスクレイピング*1

目次

コード

using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using HtmlAgilityPack;

namespace BookLogScraper
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("DLしたブクログ本棚ページhtmlのパスを入力");
            var path = Console.ReadLine();
            string htmlText = string.Empty;
            using (var sr = new StreamReader(path))
            {
                htmlText = sr.ReadToEnd();
            }

            GetBukulogList(htmlText);

            Console.ReadLine();
        }

        static void GetBukulogList(string htmlText)
        {
            var titles = new List<string>();

            var html = new HtmlAgilityPack.HtmlDocument();
            //ページを取得してhtmlパース
            html.LoadHtml(htmlText);
            
            //imgタグのやつの中で
            titles = html.DocumentNode.Descendants("img")
                ////lazyload属性があるやつの //なぜかlazyloaded属性と別れているのでまとめてlazyloadを指定
                .Where(node => node.GetAttributeValue("class", string.Empty).Contains("lazyload"))
                //alt属性の値を取得
                .Select(node => node.GetAttributeValue("alt", string.Empty))
                .ToList<string>();

            var bookTitle = string.Empty;
            //★ユーザー名は変えること
            using (var sw = new StreamWriter(@"C:\Users\xxxxx\Desktop\ブクログ本リスト.txt", false))
            {
                foreach (var title in titles)
                {
                    //"~"が"&quot;"で表示されているので置換
                    bookTitle = title.Replace("&quot;", "~");

                    Console.WriteLine(bookTitle);
                    sw.WriteLine(bookTitle);
                }
                Console.WriteLine("本の数:" + titles.Count());
                sw.WriteLine("本の数:" + titles.Count());
            }
        }
    }
}

結果

f:id:shirakamisauto:20160116181546p:plain

書き出したデータはこちら

解説

つってもページ取得は手動でやってます。
表示形式が遅延ロードになってて直接取れないので。
jQueryのlazyloadプラグイン?を使っているのかもしれない。
javascriptだとやる方法あるっぽいですが、詳しくないのでわかりません。
スクレイピングはいつものHtmlAgilityPack。
"~"が"になってるので置換しています。
他にも変な出力されてたら適宜置換処理挟んでください。

使い方

①ユーザーページの本棚を一番下までスクロールさせて全ての本を表示させます。
f:id:shirakamisauto:20160120232256p:plain
②「名前を付けてページを保存」で「Webページ、完全」で保存します。
f:id:shirakamisauto:20160120232559p:plain
③上記プログラムを起動して保存したhtmlのパスをコンソールに入力すると本一覧リストを吐き出します。
ファイル出力先パスは任意で変えてください。

*1:ぶっちゃけWebページをテキスト保存して適当に置換したり削除したりでもいいんだけどメンドイ