今回の記事はC#を用いてスクレイピングで実際のWebサイトから項目を取得する方法をご紹介する記事です。初心者にも分かりやすいように簡単に記事を記載していきますのでスクレイピングについて是非参考にしてみてください。
また、私の過去記事としていくつかリンク貼っておきますのでそちらも興味があれば是非参考にしてみてください。
「【C#】Anglesharpを用いたスクレイピング」
スクレイピングとは?
スクレイピングとは何かを理解するための説明です。わかっている方は割愛ください。
スクレイピングとは講義の意味では「こそぎ落とす」などの英語を語源としており、主にWebサイトなどから必要な情報を抽出することを意味します。
C#で行う場合は「Anglesharp」というライブラリを使うことをお勧めします。
ではWebサイトから項目などを抽出する際の手順に簡易して簡単に説明していきます。
スクレイピングの仕組み
スクレイピングの仕組み自体はAnglesharpのみでは成り立ちません。
「Anglesharp」+「http通信」
この組み合わせで基本的にはおこないます。
①http通信による通信(post・get)でWebサイトを取得
(Webサイトの取得とはディベロッパーツールなどで確認できるhtmlを全て取得すること※下記画像)
②取得したhtml(文字列)をAnglesharpでスクレイピング
(タグ・セレクタ・クラス名などで項目を指定し、文字を抽出)
流れは理解できたでしょうか?
Anglesharpでスクレイピングができるという記事をよくみますが、Anglesharpだけでhttp通信を行うメソッドもあるにはあるのですが、やはり本命のhttpclientを使う方が楽かつ一般的かと思いますのでそちらで行いましょう。
この辺り描き過去記事が参考になるかと思いますので参考にしてみてください。
「【C#】Anglesharpとhttpclientでスクレイピング」
また、Anglesharpで指定できるタグ・セレクタ・クラス名などの一覧は下記記事で確認できますのでそちらをご参考ください。
では次に進んでいきます。
Webサイトの項目一覧を取得する手順ご紹介
今回取得する項目一覧は「ユネスコ」様の世界遺産一覧から名前を取得していきます。
流れとしては下記で実装していきます。コードのみ見たい方は最後に乗っけていますのでそちらを参考にしてくてださい。
①ユネスコのトップページを取得
②トップページから項目を取得
まずはトップページを取得するために下記コードを実装します。
using System;
using System.Net.Http;
using System.Threading.Tasks;
namespace test
{
class Program
{
// httpクライアント
private static HttpClient client = new HttpClient();
static async Task Main(string[] args)
{
//サイトURL
string url = "https://www.unesco.or.jp/activities/isan/worldheritagelist/";
//サイトからのレスポンス
HttpResponseMessage Response = await client.GetAsync(url);
//レスポンスをStringに変換
string Document = await Response.Content.ReadAsStringAsync();
//出力
Console.WriteLine(Document);
}
}
}
ここではAnglesharpはまだ使っていない為、httpclientのみの仕様でサイトのhtmlを取得しております。
//サイトからのレスポンス
HttpResponseMessage Response = await client.GetAsync(url);
この部分がGet通信を行うためのメソッドでGet通信のレスポンスを取得しております。基本的にブラウザでの検索はGet通信なのでこれでページの取得はできます。Post通信はフォーム送信やログインの必要なサイトで使用することが多いです。詳しくは下記参考記事をみてください。
「【C#】AngelshrapとPost通信でスクレイピング」
レスポンスを取得し、そのレスポンスを文字列に起こします。
//レスポンスをStringに変換
string Document = await Response.Content.ReadAsStringAsync();
これを出力すると下記のようなhtml構造が確認できると思います。
<!DOCTYPE html>
<html lang="ja">
<head>
<!-- Google Tag Manager -->
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','GTM-PXFPWTN');</script>
<!-- End Google Tag Manager -->
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="description" content="公益社団法人日本ユネスコ協会連盟の事業や活動内容をご紹介しています。世界寺子屋運動・世界遺産活動・未来遺産運動・東日本大震災子ども支援募金などの活動を行っています。" />
<meta name="keywords" content="公益社団法人,日本,ユネスコ,協会連盟,UNESCO,NGO,国際連合,教育科学文化機関,世界遺産,寺子屋,未来遺産" />
<!-- OpenGraph -->
<meta property="og:title" content="公益社団法人日本ユネスコ協会連盟">
<meta property="og:description" content="公益社団法人日本ユネスコ協会連盟では、世界寺子屋運動・世界遺産活動・未来遺産運動・東日本大震災子ども支援募金などの活動を行っています。">
<meta property="og:site_name" content="公益社団法人日本ユネスコ協会連盟">
長いので残りは割愛します。
上記のhtml構造からAnglesharpを用いてスクレイピングを行っていきます。
現在取得したものは「Document」の変数に全て入っているのでこの変数を使用していきます。
ちなみにAnglesharpはNugetでライブラリを追加する必要がるので注意。VisualstudioのメニューのプロジェクトかたNugetを管理を選択し、検索してインストール。
using System;
using System.Net.Http;
using System.Threading.Tasks;
using AngleSharp.Html.Dom;
using AngleSharp.Html.Parser;
namespace test
{
class Program
{
// httpクライアント
private static HttpClient client = new HttpClient();
// htmlパーサー
private static HtmlParser parser = new HtmlParser();
static async Task Main(string[] args)
{
//サイトURL
string url = "https://www.unesco.or.jp/activities/isan/worldheritagelist/";
//Webサイトからのレスポンス
HttpResponseMessage Response = await client.GetAsync(url);
//レスポンスをStringに変換
string Document = await Response.Content.ReadAsStringAsync();
//パーサー
IHtmlDocument ParserList = await parser.ParseDocumentAsync(Document);
//例えばタイトルを抽出する場合
var title = ParserList.QuerySelector("title");
Console.WriteLine(title);
//titleを文字列として確認する場合
Console.WriteLine(title.TextContent);
}
}
}
先程の変数をAnglesharpのパーサーにセットして使用します。
//パーサー
IHtmlDocument ParserList = await parser.ParseDocumentAsync(Document);
このパーサーの形式に直せば便利なAnglesharpによって抽出できるようになります。
//QuerySelectorを使って抽出
var title = ParserList.QuerySelector("title");/
例えば「title」で抽出すると下記のような出力になります。
AngleSharp.Html.Dom.HtmlTitleElement
世界遺産一覧 – 公益社団法人日本ユネスコ協会連盟
Anglesharpのパーサの形式で出力すると中身はわからないのでtextcontentメソッドを用いて出力しましょう。
では次に対象サイトの地域別などの複数条件があるものをどのように取得するかですが下記のように実装することができます。
</div>
<div class="region">
<div class="ttl2">
<h3>ヨーロッパ②</h3>
....
<div>
<div class="region">
<div class="ttl2">
<h3>ヨーロッパ③</h3>
上記のようなイメージと構造です。
using System;
using System.Net.Http;
using System.Threading.Tasks;
using AngleSharp.Html.Dom;
using AngleSharp.Html.Parser;
namespace test
{
class Program
{
// httpクライアント
private static HttpClient client = new HttpClient();
// htmlパーサー
private static HtmlParser parser = new HtmlParser();
static async Task Main(string[] args)
{
//サイトURL
string url = "https://www.unesco.or.jp/activities/isan/worldheritagelist/";
//Webサイトからのレスポンス
HttpResponseMessage Response = await client.GetAsync(url);
//レスポンスをStringに変換
string Document = await Response.Content.ReadAsStringAsync();
//パーサー
IHtmlDocument ParserList = await parser.ParseDocumentAsync(Document);
//このように抽出条件を複数絞るなども可能
//div.ttl2(セレクタ+クラス名)は複数あるのでQuerySelectorAllで配列として取得
var infos = ParserList.QuerySelectorAll("div.ttl2");
//infosにはサイト内の上記セレクタ+クラス名で指定した要素のパーサが格納されています。
foreach (var info in infos)
{
Console.WriteLine(info.QuerySelector("h3").TextContent);
}
}
}
}
このようにサイト内の章項目などは基本的に同じセレクタ・クラス名・名前などの特徴があるのでそこを抽出のポイントにして配列として取得すると扱いやすいです。
//div.ttl2(セレクタ+クラス名)は複数あるのでQuerySelectorAllで配列として取得
var infos = ParserList.QuerySelectorAll("div.ttl2");
//infosにはサイト内の上記セレクタ+クラス名で指定した要素のパーサが格納されています。
foreach (var info in infos)
{
Console.WriteLine(info.QuerySelector("h3").TextContent);
}
出力はサイトと同じ下記のような項目一覧になっていると思います。
ヨーロッパ①
ヨーロッパ②
ヨーロッパ③
アジア①
アジア②
北米・中米
南米
オセアニア
アフリカ
以上で今回の記事は終了です。実際のサイトを使ってC#のスクレイピングを追いかけて見ました。他にも多数のC#関連の記事を記載しているので是非そちらも参考にして見てください。
コメント
[…] 「C#で実サイトにスクレイピングを行う手順」「C#でAngleSharpを使用してウェブページをスクレイピングする方法」「C#でhttp通信を行う方法。〜 Get/Post通信 〜」 […]
[…] 「C#でhttp通信を行う方法。〜 Get/Post通信 〜」「C#で実際のサイトをスクレイピングする手順」 […]