none
視窗事件:一個事件等待另一個事件?(IHTMLDocument3 ,axWebBrowser1_NewWindow3 ,webBrowser1_DocumentCompleted) RRS feed

  • 一般討論

  • 大家好:

    我想抓取網頁原始碼中的資料

    說明:我必須先登入,

           登入後有A頁面,

           A頁面之中有十個連結 ( 網頁原始碼ex. <a id = "1" href = "1.html" target = "_blank">1</a> )

           也就是說點擊1連結之後, 會開啟一個新視窗1.html

    問題:如何取得十個連結中, n.html的原始碼

    我的做法:

             private void button1_Click(object sender, EventArgs e)
            {
                IHTMLDocument3 htmlDoc = (IHTMLDocument3)axWebBrowser1.Document;
                IHTMLElementCollection a =  htmlDoc.getElementsByTagName("a");

                foreach (IHTMLElement b in a)
                {
                    if (b.id!=null && b.id.Contains("1~10"))
                        b.click();  //自動點擊連結
                }

            }

            private void axWebBrowser1_NewWindow3(object sender, AxSHDocVw.DWebBrowserEvents2_NewWindow3Event e)
            {
                e.cancel =true;
                webBrowser1.Navigate(e.bstrUrl);            
            }

            private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
            {
                do Something.....
            }

    結果: 只能讀到10.html的原始碼

            似乎是因為每點擊一次,還未下載完網頁資料就點擊了下一次

            有其他方法嗎???????

            有辦法做到b.click();之後觸發axWebBrowser1_NewWindow3,然後等到webBrowser1_DocumentCompleted之後再回到b.click()嗎??????

            也許是我觀念不對, 請各位多多指教!!!謝謝大家........



    2012年10月19日 下午 05:10

所有回覆

  • 你用迴圈一定會這樣, 因為 Navigate 這個 Method 會使用非同步的方式載入網頁, 所以你根本就沒有完成前一個網頁的載入動作就接著載入下一個.

    基本上有一種類似遞迴的解法.

    宣告一個全域的 int 變數, 用來控制次數

    每當進到 DocumentCompleted 事件委派函式做完你該做的處理後將int 變數+1

    當該 int變數小於某個值的時候再度呼叫 Navigate 方法.

    就這樣.


    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。

    2012年10月20日 上午 01:53
    版主
  • 感謝Bill Chung的回答

    但是我不太懂

    如果可以是否更詳細的再說明一次

    謝謝

    2012年10月20日 下午 04:55
  • (1) 在類別內宣告一個 int 型別的變數

    int loadcount =0;

    (2) 把 button.click 中的迴圈拿掉. 只要呼叫一次 webBrowser1.Navigate(e.bstrUrl);

    (3) 在 webBrowser1_DocumentCompleted 處理完你想處理的事後, 寫一個判斷式

    if (loadcount < 10)

    { loadcount++;

       webBrowser1.Navigate(e.bstrUrl); }

    以上只是示意代碼, 大致是這個概念


    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。

    2012年10月21日 上午 02:35
    版主
  • 感謝Bill Chung的回答

    這樣可能也沒辦法

    1.請注意foreach迴圈是無法拿掉的, 此網頁可能有30個連結, 因此我加上判斷取得其中十個連結, 前提是我只有用此種方法才可以取得連結

    2.再注意一個, axWebBrowser1 和 WebBrowser1 是兩個不同的瀏覽器

    謝謝您熱心的回答與幫忙

    2012年10月21日 下午 04:00
  • 只是要html的話,改用WebRequest比較容易一些
    2012年10月21日 下午 04:17