2011-10-18 42 views
0

看來,我遇到了一些簡單的嘗試解析一些HTML的問題。作爲練習,我寫了一個多線程的網絡爬蟲,它以一系列要爬行的網站開始。這通過幾個類傳遞下來,最終應該將網站的內容返回給我的系統。這看起來相當簡單,但我在以下兩項任務中都沒有運氣:C#Web解析衝突

A.將網站的內容(字符串格式,從HttpWebRequest流)轉換爲HtmlDocument(無法創建新實例的HtmlDocument?沒有多大意義...)通過使用HtmlDocument.Write()方法。

B.通過WebBrowser實例收集HtmlDocument。

這裏是我的代碼,因爲它存在,任何建議將是巨大的......

public void Start() 
    { 
     if (this.RunningThread == null) 
     { 
      Console.WriteLine("Executing SiteCrawler for " + SiteRoot.DnsSafeHost); 

      this.RunningThread = new Thread(this.Start); 
      this.RunningThread.SetApartmentState(ApartmentState.STA); 
      this.RunningThread.Start(); 
     } 
     else 
     { 
      try 
      { 
       WebBrowser BrowserEmulator = new WebBrowser(); 
       BrowserEmulator.Navigate(this.SiteRoot); 

       HtmlElementCollection LinkCollection = BrowserEmulator.Document.GetElementsByTagName("a"); 
       List<PageCrawler> PageCrawlerList = new List<PageCrawler>(); 

       foreach (HtmlElement Link in LinkCollection) 
       { 
        PageCrawlerList.Add(new PageCrawler(Link.GetAttribute("href"), true)); 
        continue; 
       } 
       return; 
      } 
      catch (Exception e) 
      { 
       throw new Exception("Exception encountered in SiteCrawler: " + e.Message); 
      } 
     } 
    } 

此代碼似乎當它經過了「導航」的方法什麼也不做。我試圖讓它在一個新的窗口中打開,這個窗口彈出一個新的IE實例,然後繼續導航到指定的地址,但是在我的程序執行導航方法之前不會。我試過等待瀏覽器「不忙」,但它似乎從來沒有拿起繁忙的屬性。我已經嘗試通過Browser.Document.OpenNew()創建一個新文檔,以便我可以使用來自WebRequest流的數據填充它,但是,我確定您可以假設當我試圖通過該聲明的「文件」部分。我已經做了一些研究,這似乎是創建新的HtmlDocument的唯一方法。

如您所見,此方法旨在爲指定頁面中的每個鏈接啓動「PageCrawler」。我確信,在使用HttpWebRequest並從流中收集數據之後,我可以通過字符來分析HTML字符以找到所有鏈接,但這比完成此操作所需的工作要多得多。

如果有人有任何建議,將不勝感激。謝謝。

+0

考慮使用http://www.codedblog.com/2007/08/29/google-web-toolkit-and-c/ –

+0

當我試圖測試你的代碼時,我得到了關於'this.RunningThread'的編譯器錯誤' this.SiteRoot'' PageCrawler'等等。我想你猜測猜測不是真正的答案。 –

回答

1

如果這是一個控制檯應用程序,那麼它將不起作用,因爲控制檯應用程序沒有消息泵(WebBrowser需要處理消息)。

如果你運行這個在Windows窗體應用程序,那麼你就應該處理DocumentCompleted事件:

WebBrowser browserEmulator = new WebBrowser(); 
browserEmulator.DocumentCompleted += OnDocumentCompleted; 
browserEmulator.Navigate(this.SiteRoot); 

然後實現處理該事件的方法:

private void OnDocCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) 
{ 
    WebBrowser wb = sender as WebBrowser; 

    if (wb.Document != null) 
    { 
     List<string> links = new List<string>(); 

     foreach (HtmlElement element in wb.Document.GetElementsByTagName("a")) 
     { 
      links.Add(element.GetAttribute("href")); 
     } 

     foreach (string link in links) 
     { 
      Console.WriteLine(link); 
     } 
    } 
} 

如果你想在控制檯應用程序中運行這個,那麼你需要使用不同的方法來下載頁面。我建議您使用WebRequest/WebResponse,然後使用HtmlAgilityPack解析HTML。 HtmlAgilityPack將爲您生成一個HtmlDocument,您可以從那裏獲取鏈接。


此外,如果你有興趣瞭解更多關於構建可擴展的網絡爬蟲,那麼請查看以下鏈接:

祝你好運!

+0

正義的男人,感謝您的建議,我必須去抓住敏捷包,我只是想把一個代碼示例放在一起發送到我的簡歷幾個地方,爬行者似乎是一個相當簡單的,所有的解決方案。 – DigitalJedi805

+0

@ DigitalJedi805如果您對答案滿意,請確保您通過勾選答案旁邊的複選標記來授予獲勝者。謝謝! :) – Kiril