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