最近有個小程序需要采集網頁源代碼,但有的網頁中JS腳本又會生成額外的代碼,比如http://www.cnblogs.com/lidabo/p/4169396.html
紅框部分便是另外加載的代碼。
此處可以看到web前端是有 "操作系統" 幾個字的,但查看網頁源代碼之后卻搜不到這幾個字
C#有個webbrowser控件可以等網頁加載完之后獲取瀏覽器上所有的網頁源代碼(也包括額外被JS加載進來的代碼)
【第一次】試驗
WebBrowser webBrowser1 = new WebBrowser();
private void button1_Click(object sender, EventArgs e)
{
webBrowser1.Navigate("http://www.cnblogs.com/lidabo/p/4169396.html");
//加載完畢后觸發事件webBrowser1_DocumentCompleted
webBrowser1.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(webBrowser1_DocumentCompleted);
}
private void webBrowser1_DocumentCompleted(object sender, EventArgs e)//這個就是當網頁載入完畢后要進行的操作
{
//將webBrowser顯示的代碼傳入richTextBox以便調試
richTextBox1.Text = webBrowser1.DocumentText;
}
結果:webbrowser加載完這個頁面之后,richTextBox1.Text獲取的代碼里面找不到 "操作系統" 幾個字 , 獲取的代碼有1063行
網頁在加載的過程中,webBrowser1_DocumentCompleted可能會觸發一次以上,且相同網頁可能觸發次數不盡相同
有的網頁會多次觸發webBrowser1_DocumentCompleted,騰訊網http://www.qq.com觸發了4次
【第二次】試驗
public int i;//設置全局變量i
private void webBrowser1_DocumentCompleted(object sender, EventArgs e)
{
i++;//以便觀察這個事件被觸發了多少次
richTextBox1.Text = webBrowser1.DocumentText;
}
結果:最后 i 的值為 1,richTextBox1.Text獲取的代碼里面依然找不到 "操作系統" 幾個字 , 獲取的代碼有1063行
按理來說不應該只觸發一次、
【第三次】試驗
private void webBrowser1_DocumentCompleted(object sender, EventArgs e)
{
MessageBox.Show("111");//這個得迅速點掉確定才看到觸發了多少次messagebox
richTextBox1.Text = webBrowser1.DocumentText;
}
結果:迅速點掉messagebox的“確定”后又出現了一次messagebox,即一共兩次觸發了webBrowser1_DocumentCompleted事件
實驗觸發二次webBrowser1_DocumentCompleted事件,里面可以找到"操作系統"幾個字,代碼共有2095行,這次應該全部獲取完畢了
加入沒有迅速點掉messagebox,可能這個等待過程中,網頁可能被webbrowser真的完全加載完畢從而不再觸發webBrowser1_DocumentCompleted事件
為什么
【第二次】實驗只觸發一次webBrowser1_DocumentCompleted事件,而且獲取的代碼還不完全
【第三次】實驗加入了messagebox(然后迅速點掉)能觸發一次以上的webBrowser1_DocumentCompleted事件,獲取代碼完全
【第三次】實驗加入了messagebox(沒有迅速點掉)只能觸發一次webBrowser1_DocumentCompleted事件,獲取代碼完全
我沒弄明白
***********************************************************************************************************
那么換個思路。在第一次進入webBrowser1_DocumentCompleted事件之時開啟一個timer時鍾,間隔5秒,5秒之后獲取一次webbrowser的代碼
只觸發一次時鍾時間,由於時鍾是另外的線程,要調用webbrowser需要用到委托
//實例化timer
System.Timers.Timer t = new System.Timers.Timer();
//定義委托變量
public happy updateTxt_ok;
public delegate void happy();
public Form1()
{
InitializeComponent();
//設定timer
t.Interval = 5000; //定時,單位ms
t.Enabled = true; //回調函數允許執行
t.AutoReset = false; //回調函數循環執行
t.Elapsed += new System.Timers.ElapsedEventHandler(theout); //到達時間的時候執行事件;
t.Stop();
}
private void Form1_Load(object sender, EventArgs e)
{
updateTxt_ok = new happy(UpdateTxtMethod);
}
//委托執行函數
public void UpdateTxtMethod()
{
//此處不用DocumentText是因為它獲取中文可能產生亂碼
Encoding encoding = Encoding.GetEncoding(webBrowser1.Document.Encoding);
StreamReader stream = new StreamReader(webBrowser1.DocumentStream, encoding);
string aa = stream.ReadToEnd();
richTextBox1.Text = aa;
stream.Close();
}
//timer事件
public void theout(object source, System.Timers.ElapsedEventArgs e)
{
this.BeginInvoke(updateTxt_ok);//委托執行updateTxt_ok
}
//按下按鈕
private void button1_Click(object sender, EventArgs e)
{
webBrowser1.Navigate(richTextBox1.Text);
webBrowser1.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(webBrowser1_DocumentCompleted);
}
private void webBrowser1_DocumentCompleted(object sender, EventArgs e)//這個就是當網頁載入完畢后要進行的操作
{
t.start();//開啟時鍾
}
結果:獲取完整源代碼,共有2095行
但不能保證其他網頁也是延遲5秒就能加載完,有的服務器很卡,需要調整時間