C#でMSHTMLを使ってHTMLのパース

piy2010-03-03


windowsアプリケーションを創るなら、C#のほうが楽そうだ
と思ってMFCを離れてC#に挑戦してみる。



ファイルをダウンロードするアプリケーションを作りたいので、
MSHTMLとやらを使ってHTMLのパースをしてみる。



手始めに、↓を参考にデッドリンクチェッカーを作る。

http://msdn.microsoft.com/ja-jp/academic/cc998633.aspx
第 3 回 VC# で MSHTML テクノロ
〜 Visual C# .NET による MSDNAA おもしろプログラミング 〜

このページ、VC#や.Netのバージョンが古くて微妙に参考にならない。
http://watcher.moe-nifty.com/memo/2007/03/vc_mshtml_net_f_8178.htmlを参考にしたりして、
なんとかできた。

  • 3.3.3 フォームの作成の(1) コントロールの配置では「Web Browser」を追加
  • btnCheckLink_Click関数を下のように書いたら、なんとか動いた
        private void btnCheckLink_Click(object sender, EventArgs e)
        {
            //初期化
            object oNull = null;
            // AxSHDocVw.AxWebBrowser myWebBrowser = new AxSHDocVw.AxWebBrowser(); 

            lstLinks.Items.Clear();//listboxのクリア
            System.Collections.ArrayList myATags = new System.Collections.ArrayList();

            //ドキュメントオブジェクトの取得
            mshtml.HTMLDocument myDocment = (mshtml.HTMLDocument)axWebBrowser1.Document.DomDocument;

            // Aタグの取得
            mshtml.IHTMLElementCollection cATags = myDocment.getElementsByTagName("a");
            IEnumerator ee = cATags.GetEnumerator();
            while (ee.MoveNext()) {
                mshtml.HTMLAnchorElementClass aATag = (mshtml.HTMLAnchorElementClass)ee.Current;
                string sBuffer = aATag.href;


                //メールリンクではない場合
                if (sBuffer.IndexOf("mailto:") < 0)
                {
                    ATag oAtag = new ATag();
                    oAtag.Href = aATag.href;
                    oAtag.InnerText = aATag.innerText;
                    myATags.Add((object)oAtag);
                }
            
            }
            //Aタグチェック
            ee = myATags.GetEnumerator();
            while (ee.MoveNext()) {
                ATag aATag = (ATag)ee.Current;

                //webページの読み込み処理
                axWebBrowser1.Navigate(aATag.Href);

                do
                {
                    Application.DoEvents();
                }
                while (axWebBrowser1.ReadyState == WebBrowserReadyState.Loading);
                mshtml.HTMLDocument myDocment2 = (mshtml.HTMLDocument)axWebBrowser1.Document.DomDocument;
                Application.DoEvents();

                //デッドリンクの場合
                if (myDocment2.title == "サーバーが見つかりません")
                {
                    lstLinks.Items.Add("× " + aATag.InnerText);

                }
                //正常パターン
                else {
                    lstLinks.Items.Add("○ " + aATag.InnerText);                
                }
            }
            MessageBox.Show("処理が正常終了しました");
        }

環境:windows7 32bit, Visual Stdio 2005, IE8



C#は今月始めたばっかりなので、ものすごい勘違いとかあるかもしれません。
あと、mshtmlが膨大すぎて、マジで意味不明。