C#でスクレイピング

2009/12/23 追記
最下段に参考文献として、ここで紹介した以外の方法へのリンクが有ります。

C#でHTMLを読み込んで、HTMLから有益な情報を取り出したいときってありますよね。
でも正規表現とかで抜き出すのってカッコ悪い、と思います。
そこで、「InfoPath SDKについてるHTMLtoXHTMLというCOMコンポーネント」を使ってXPath式で情報を取得します。
インストール方法は↓のURLを参照してください。
C#でスクレイピング - DENKEN
以下に実際に動くソースコードを貼っておきます。LINQとか使わない.Net Framework 2.0対応です。

using System.Xml;
using HTML2XHTMLLib;

namespace hogehoge
{
  public class Hoge
  {
    /// <summary>コンストラクタ</summary>
    /// <param name="contents">ページ内容(HTML)</param>
    public Hoge(string contents)
    {
      if((contents ?? "").Length == 0) return;
      XmlElement root;
      XmlNamespaceManager nsmgr;
      XHTMLUtilities util = new XHTMLUtilities();
      
      { // HTMLをXHTMLに変換する
        string xhtml = util.convertToXHTML(contents);
        // しかし、XMLとして読み込むには不完全なため、微調整をする必要がある
        xhtml = xhtml.Replace("\"checked=", "\" checked="); // 
        
        // XMLとして読み込む
        XmlDocument xdoc = new XmlDocument();
        xdoc.LoadXml(xhtml);
        
        // ルートノードの取得
        root = xdoc.DocumentElement;
        
        // ネームスペースの作成
        nsmgr = new XmlNamespaceManager(xdoc.NameTable);
        // なんでもいいから、必ず作成する
        nsmgr.AddNamespace("ns", "http://www.w3.org/1999/xhtml");
      }
      
      // <title>タグの中に書かれているテキストを取得
      // Namespaceが無くても必ず指定する
      string title = root.SelectSingleNode("//ns:title", nsmgr).InnerText;
      
      // <a href="hoge...">リンク先がhogeで始まるリンクを全て取得
      foreach(XmlNode node in root.SelectNodes("//ns:a[starts-with(@href, 'hoge')]", nsmgr))
      {
        string link = node.InnerText;
      }
      
      // XPath式の書き方は他のページを参照してください
      XmlNode node2 = root.SelectSingleNode("./ns:body/ns:div[@class='hoge']", nsmgr);
    }
  }
}

使う側は、こんな感じで。

hogehoge.Hoge hoge = new hogehoge.Hoge("<html><head><title>タイトル</title></head><body><a href=\"hogehoge\">リンク先へ</a><div class=\"hoge\"></div></body></html>");

配布先で使ってもらうには、html2xhtml.dllを配るだけじゃダメなようで、html2xhtml.dllがあるディレクトリで次のコマンドを打ってもらう必要があるようです。

 > regsvr32 html2xhtml.dll