スクレイピングのコード
前ページのサンプルのコードは以下の通りです。Visual Studioのプロジェクトでは「HtmlAgilityPack.dll」に参照設定を行っておきます。
WEBサイトにアクセスして情報を抽出するコード(C#)
using HtmlAgilityPack;
(中略)
private void button1_Click(object sender, EventArgs e)
{
//(1)Webサイトに接続してHTMLを取得
const string url = "http://journal.mycom.co.jp/enterprise/";
System.Net.WebClient web = new System.Net.WebClient();
string html = web.DownloadString(url);
//(2)HtmlDocumentクラスにHTMLをセット
HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
doc.LoadHtml(html);
//(3)XPathを使ってランキング情報の<a>コレクションを抽出
HtmlNodeCollection nodes =
doc.DocumentNode.SelectNodes(@"//ul[@id=""todayRanking""]//a");
//(4)<a>コレクションから値を取り出し
foreach (HtmlNode node in nodes)
{
//テキストをセット
textBox1.Text += node.InnerText + "\r\n";
//リンクをセット
textBox1.Text += node.Attributes["href"].Value + "\r\n";
}
}
コードの内容について見ていきましょう。
(1)Webサイトに接続
まずWebサイトにアクセスしてHTMLをダウンロードします。ここでは、WebClientクラス(System.Net名前空間)を利用しています。HAPにはWebサイトアクセス用のHtmlWebというクラスが用意されていますが、shift_jisのような日本語文字コードを処理できなかったため本稿では利用していません(UTF-8の場合は問題なく利用できました)。
Webサイトから取得したHTMLは以下の通りです。
(2)HTMLをHtmlDocumentクラスにセット
次に、HTMLをDOMと呼ばれる構造に展開します。そのためHtmlDocumentクラス(HtmlAgilityPack名前空間)を利用します。LoadHtmlメソッドを呼び出すとHTMLがDOMツリーに展開されます。これによってDocumentNodeプロパティからHTMLのルート要素にアクセスできるようになります。
なお、System.Windows.Forms名前空間にもHtmlDocumentクラスが存在しますので、Windowsフォームで使用する時はご注意ください。
(3)XPathを使って今日のランキング情報を抽出
次に、SelectNodesメソッドを使ってHTMLから必要な部分を抽出します。ここではXPathを「SelectNodes(@"//ul[@id=""todayRanking""]//a")」と指定して「todayRankingというid属性を持つul配下の全aノード」を取得しています。この結果、HtmlNode(HTMLノードを表すクラス)が複数格納されたHtmlNodeCollectionを取得できます。
(4)テキストボックスに文字列とリンクを設定
最後に表示する値を取得します。HtmlNodeCollectionクラスに<a>ノードのコレクションが格納されているため、InnerTextプロパティでタグ間の文字列を取得し、Attributes["href"].Valueプロパティでhref属性のURLを取得しています。
なお、今回はXPathの指定だけで必要なノードを絞り込めましたが、複雑な条件の場合には「nodes.Where(n => n.Attributes["href"].Value.Contains("絞り込み文字"))」のように、コレクションに対してフィルタリングを行うと良いでしょう。
最後に
ここではHtml Agility Packについて紹介しました。HAPはデータを抽出するだけではなく、HTMLをXMLとして保存したり、XSLTと組み合わせて別の形式(RSSフィード等)で出力したりできます。またIronPythonからツール的に利用したり、ASP.NETでマッシュアップしたりもできます。もし、HAPに興味をもたれた方は、一度ダウンロードしてみてはいかがでしょうか。