tag:crieit.net,2005:https://crieit.net/tags/AngleSharp/feed
「AngleSharp」の記事 - Crieit
Crieitでタグ「AngleSharp」に投稿された最近の記事
2020-10-06T00:33:41+09:00
https://crieit.net/tags/AngleSharp/feed
tag:crieit.net,2005:PublicArticle/16115
2020-10-06T00:33:41+09:00
2020-10-06T00:33:41+09:00
https://crieit.net/posts/NET-Core-HttpClient-AngleSharp-UTF-8
.NET Core + HttpClient + AngleSharp で UTF-8 ではないサイトをスクレイピングする
<p>この記事は Qrunch からの移植記事です。<br />
元記事は 2019/08/29 に書かれており、記事の内容が現状と即していない可能性が大いにあります。<br />
<a target="_blank" rel="nofollow noopener" href="https://nokoq16.qrunch.io/entries/YtBflMEtJiDnOak3">元記事</a></p>
<p>以下から本文です。</p>
<hr />
<p>タイトル通りなのですが、文字コード絡みで少しハマったので備忘がてら記事化しました。</p>
<h2 id="事の経緯"><a href="#%E4%BA%8B%E3%81%AE%E7%B5%8C%E7%B7%AF">事の経緯</a></h2>
<ol>
<li>AngleSharp によるスクレイピングを試したくなる</li>
<li>何気なしに 4Gamer.net さんのサイトで試す</li>
<li>記事タイトルの取得を試みたところ盛大に文字化けしている</li>
<li>なんでや!?</li>
<li>charset で EUC-JP が指定されとるやんけ!</li>
</ol>
<p>という感じです。<br />
このご時世に初手で UTF-8 ではないサイトを引き当てるとは思いませんでした。</p>
<h2 id="要点"><a href="#%E8%A6%81%E7%82%B9">要点</a></h2>
<ul>
<li>HttpClient.GetStreamAsync で Stream を取得して StreamReader で読み込む際に文字コードを指定する
<ul>
<li>HttpClient.GetStringAsync で string を取得したあと文字コード指定で Convert しようとしてもダメ</li>
</ul></li>
<li>.NET Core は素のままだと Shift_JIS や EUC-JP に対応していないのでエンコードプロバイダーを追加する
<ul>
<li><del>.NET Core あんまり触ってないから知らなかった</del></li>
</ul></li>
</ul>
<h2 id="サンプルコード"><a href="#%E3%82%B5%E3%83%B3%E3%83%97%E3%83%AB%E3%82%B3%E3%83%BC%E3%83%89">サンプルコード</a></h2>
<pre><code class="csharp">// .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);
}
</code></pre>
<h2 id="参考記事"><a href="#%E5%8F%82%E8%80%83%E8%A8%98%E4%BA%8B">参考記事</a></h2>
<p>AngleSharp を使うにあたり以下の記事を参考にしました。<br />
ありがとうございます。<br />
<a target="_blank" rel="nofollow noopener" href="https://qiita.com/Yuzu_Unity/items/48d00f2a4779f360d2de">Unity上でAngleSharpを利用したスクレイピングを行う</a><br />
<a target="_blank" rel="nofollow noopener" href="https://qiita.com/NekozeDaisensei/items/c74f71e5d79d6de05841">【C#】AngleSharpの使い方メモ</a></p>
<h2 id="最後に"><a href="#%E6%9C%80%E5%BE%8C%E3%81%AB">最後に</a></h2>
<p><del>4Gamer.net さん EUC-JP 止めて UTF-8 にして</del></p>
kono 16