ASP.net經過WebBrowser取得AJAX後的網頁

今天  Shih-Min 問我說,假設網頁一開始是AJAX 會載入一些資料,可是透過WebClient 去抓html

抓到都是JavaScript 跟 AJAX 的原始碼,有辦法能夠抓到AJAX 取完值以後的資料嗎?!web

 

這需求,若是寫爬蟲可能也會有這需求..個人做法是這樣..安全

我是ASP.net 專案..url

創建一個Class 記得要加入 System.Windows.Formsspa

 

\
 

這時候我創建一隻 Class 叫作 WebBrowserCrawler.net

 

using System.Threading;
using System.Windows.Forms;
 
namespace GetAfterAJAXPage
{
 
 
 
    public class WebBrowserCrawler
    {
        // WebBrowser
        private WebBrowser _WebBrowder;
 
        //最後結果
        private string _Result { get; set; }
 
        //網址
        private string _Path { get; set; }
 
      
        /// <summary>
        /// 對外公開的Method
        /// </summary> www.it165.net
        /// <param name="url">URL Path</param>
        /// <returns></returns>
        public string GetReult(string url)
        {
 
            _Path = url;
 
 
            var mThread = new Thread(FatchDataToResult);
            //Apartment 是處理序當中讓物件共享相同執行緒存取需求的邏輯容器。 同一 Apartment 內的全部物件都能收到 Apartment 內任何執行緒所發出的呼叫。 
            //.NET Framework 並不使用 Apartment;Managed 物件必須自行以安全執行緒 (Thread-Safe) 的方式運用一切共享資源。
            //由於 COM 類別使用 Apartment,因此 Common Language Runtime 在 COM Interop 的情況下呼叫出 COM 物件時必須創建 Apartment 而且加以初始化。 
            //Managed 執行緒能夠創建而且輸入只允許一個執行緒的單一執行緒 Apartment (STA),或者含有一個以上執行緒的多執行緒 Apartment (MTA)。 
            //只要把執行緒的 ApartmentState 屬性設定爲其中一個 ApartmentState 列舉型別 (Enumeration),便可控制所創建的 Apartment 屬於哪一種型別。 
            //由於特定執行緒一次只能初始化一個 COM Apartment,因此第一次呼叫 Unmanaged 程式碼以後就沒法再變動 Apartment 型別。
            //From : http://msdn.microsoft.com/zh-tw/library/system.threading.apartmentstate.aspx
            mThread.SetApartmentState(ApartmentState.STA);
            mThread.Start();
            mThread.Join();
 
            return _Result;
 
        }
 
        /// <summary>
        /// Call _WebBrowder 抓取資料
        /// For thread Call
        /// </summary>
        private void FatchDataToResult()
        {
            
            _WebBrowder = new WebBrowser();
 
            _WebBrowder.DocumentCompleted += _WebBrowder_DocumentCompleted;
            _WebBrowder.Navigate(_Path);
 
 
            //處理目前在訊息佇列中的全部 Windows 訊息。
            //若是在程式碼中呼叫 DoEvents,您的應用程式就能夠處理其餘事件。例如,若是您的表單將資料加入 ListBox 並將 DoEvents 加入程式碼中,則當另外一個視窗拖到您的表單上時,該表單將從新繪製。
            //若是您從程式碼移除 DoEvents,您的表單將不會從新繪製,直到按鈕按一下的事件處理常式執行完畢。
            while (_WebBrowder.ReadyState != WebBrowserReadyState.Complete)
            {
                Application.DoEvents();
            }
 
            _WebBrowder.Dispose();
 
        }
 
        //結束後回填
        void _WebBrowder_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
        {
            _Result = (sender as WebBrowser).Document.Body.InnerHtml;
            
        }
 
 
    }
 
 
}

爲什要這樣寫 經過Thread 來叫用否則會遇到code

 

\
 

\
 

以後我呼叫端:
 orm

1. WebBrowserCrawler  webBrowserCrawler=new WebBrowserCrawler();
2. File.WriteAllText(Server.MapPath("sample.txt"),webBrowserCrawler.GetReult(http://www.in2.cc/sample/waterfalllab.htm));


其中我是將取得後的資料寫入到sample.txt 中… htm

相關文章
相關標籤/搜索