2020-10-06に投稿

.NET Core + HttpClient + AngleSharp で UTF-8 ではないサイトをスクレイピングする

この記事は Qrunch からの移植記事です。
元記事は 2019/08/29 に書かれており、記事の内容が現状と即していない可能性が大いにあります。
元記事

以下から本文です。


タイトル通りなのですが、文字コード絡みで少しハマったので備忘がてら記事化しました。

事の経緯

  1. AngleSharp によるスクレイピングを試したくなる
  2. 何気なしに 4Gamer.net さんのサイトで試す
  3. 記事タイトルの取得を試みたところ盛大に文字化けしている
  4. なんでや!?
  5. charset で EUC-JP が指定されとるやんけ!

という感じです。
このご時世に初手で UTF-8 ではないサイトを引き当てるとは思いませんでした。

要点

  • HttpClient.GetStreamAsync で Stream を取得して StreamReader で読み込む際に文字コードを指定する
    • HttpClient.GetStringAsync で string を取得したあと文字コード指定で Convert しようとしてもダメ
  • .NET Core は素のままだと Shift_JIS や EUC-JP に対応していないのでエンコードプロバイダーを追加する
    • .NET Core あんまり触ってないから知らなかった

サンプルコード

// .NET Core は素のままだと Shift_JIS や EUC-JP に対応していないのでエンコードプロバイダーを追加
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);

// HttpClient でスクレイピングしたいサイトの HTML を取得する
HttpClient httpClient = new ServiceCollection()
                .AddHttpClient()
                .BuildServiceProvider()
                .GetService<IHttpClientFactory>()
                .CreateClient();

Stream htmlStream = httpClient.GetStreamAsync("https://www.4gamer.net/").Result;

string htmlString;
using (var reader = new StreamReader(htmlStream, Encoding.GetEncoding("EUC-JP"), true) as TextReader)
{
    htmlString = reader.ReadToEnd();
}

// h2 > a > InnerText ≒ 記事タイトルを取得する
var parser = new HtmlParser();
IHtmlDocument doc = parser.ParseDocument(htmlString);
IHtmlCollection<IElement> h2Collection = doc.QuerySelectorAll("h2");
IEnumerable<string> articleTitles = h2Collection.Select(x => x.QuerySelector("a").InnerHtml);

// 煮るなり焼くなり好きにする
foreach (var articleTitle in articleTitles)
{
    Trace.WriteLine(articleTitle);
}

参考記事

AngleSharp を使うにあたり以下の記事を参考にしました。
ありがとうございます。
Unity上でAngleSharpを利用したスクレイピングを行う
【C#】AngleSharpの使い方メモ

最後に

4Gamer.net さん EUC-JP 止めて UTF-8 にして

ツイッターでシェア
みんなに共有、忘れないようにメモ

kono 16

しがない C#er です。

Crieitは誰でも投稿できるサービスです。 是非記事の投稿をお願いします。どんな軽い内容でも投稿できます。

また、「こんな記事が読みたいけど見つからない!」という方は是非記事投稿リクエストボードへ!

有料記事を販売できるようになりました!

こじんまりと作業ログやメモ、進捗を書き残しておきたい方はボード機能をご利用ください。
ボードとは?

コメント