倔強的網站數據抓取,關鍵時刻還需Webbrowser顯身手 - 施瓦小辛格

>>>  技術話題—商業文明的嶄新時代  >>> 簡體     傳統

       由于最近臺風挺多,公司網站上需要掛上臺風預報信息,就整了個抓取臺風數據(至于抓數據的概念和實踐手冊我以前寫的一篇博客里面有介紹:分享一套抓數據小程序,客戶資料、實時新聞、股票數據隨心抓的服務,做調試階段,發現個詭異的問題。如下:

      需要抓取的數據是個xml文件,地址如下:http://typhoon.weather.gov.cn/Typhoon/data/20130041.xml,這是政府氣象網發布的最近某個臺風的數據信息,具體代表什么意思不是本文研究的范疇,有興趣的可以研究研究。

1. 首先我用WebClient去請求此地址,核心代碼如下:

1  WebClient wc = new WebClient();2  wc.Encoding = Encoding.UTF8;3 string str = wc.DownloadString("http://typhoon.weather.gov.cn/Typhoon/data/20130041.xml");

獲取到的數據節點如下:

<typhoon>
<key YMDHM="2013101612" V05="11.6" V06="143.1" V07="8" V08="18" V09="998" V11="5" V12="NW" V21="150" V22="0">...</key>
<key YMDHM="2013101618" V05="11.2" V06="142.8" V07="8" V08="20" V09="996" V11="5" V12="NW" V21="160" V22="0">...</key>
<key YMDHM="2013101700" V05="11.1" V06="142.7" V07="11" V08="30" V09="980" V11="8" V12="NNW" V21="260" V22="60">...</key>
<key YMDHM="2013101706" V05="11.3" V06="142.7" V07="12" V08="35" V09="970" V11="15" V12="NNW" V21="280" V22="80">...</key>
<key YMDHM="2013101712" V05="12.1" V06="142.8" V07="13" V08="40" V09="960" V11="15" V12="NNW" V21="300" V22="100">...</key>
<key YMDHM="2013101718" V05="13.1" V06="142.6" V07="14" V08="42" V09="955" V11="16" V12="NNW" V21="320" V22="110">...</key>
<key YMDHM="2013101800" V05="13.8" V06="142.2" V07="15" V08="50" V09="940" V11="15" V12="NNW" V21="350" V22="120">...</key>
<key YMDHM="2013101806" V05="14.2" V06="142" V07="16" V08="55" V09="930" V11="15" V12="NW" V21="350" V22="130">...</key>
<key YMDHM="2013101812" V05="15.2" V06="141.8" V07="16" V08="55" V09="930" V11="15" V12="NW" V21="350" V22="130">...</key>
<key YMDHM="2013101818" V05="15.9" V06="141.1" V07="17" V08="60" V09="920" V11="15" V12="NW" V21="350" V22="130">...</key>
<key YMDHM="2013101900" V05="16.1" V06="140.5" V07="17" V08="60" V09="920" V11="15" V12="NW" V21="350" V22="130">...</key>
<key YMDHM="2013101906" V05="16.7" V06="139.7" V07="17" V08="60" V09="920" V11="13" V12="NW" V21="350" V22="130">...</key>
<key YMDHM="2013101912" V05="17.1" V06="139.1" V07="18" V08="62" V09="915" V11="13" V12="NW" V21="350" V22="150">...</key>
<key YMDHM="2013101918" V05="17.5" V06="138.3" V07="18" V08="62" V09="915" V11="13" V12="NW" V21="350" V22="150">...</key>
<key YMDHM="2013102000" V05="17.8" V06="137.7" V07="18" V08="62" V09="915" V11="10" V12="NNW" V21="350" V22="150">...</key>
<key YMDHM="2013102006" V05="18.4" V06="137.3" V07="18" V08="62" V09="915" V11="12" V12="NNW" V21="350" V22="150">...</key>
<key YMDHM="2013102012" V05="18.8" V06="136.8" V07="17" V08="58" V09="925" V11="10" V12="NNW" V21="350" V22="150">...</key>
</typhoon>


和從瀏覽器中打開顯示的數據總是少最后兩個節點(如下),至于為什么少兩個節點,和幾個大牛探討了下,猜測可能是由于官方網站為了保護他自己的最新數據,提高了獲取數據的門檻。

<key YMDHM="2013102018" V05="19.3" V06="136.6" V07="16" V08="52" V09="938" V11="10" V12="NNW" V21="300" V22="100">...</key>
<key YMDHM="2013102100" V05="19.7" V06="136.2" V07="15" V08="50" V09="940" V11="11" V12="NNW" V21="300" V22="100">...</key>


2.此路不通,換個方法,這次我選擇使用Http請求去獲取,核心代碼如下:

        /// <summary>/// 傳入get請求地址,和頁面編碼格式,返回該頁面html源文件,返回wrong則出現異常。/// </summary>/// <param name="tUrl">傳入url</param>/// <param name="encodeType">傳入 頁面的編碼格式</param>/// <returns></returns>internal static string Get_HttpAll(string tUrl, string encodeType)
        {string strResult;try{
                HttpWebRequest hwr = CreateHttpWebRequest(tUrl);
                hwr.Timeout = 19990;
                CookieContainer cc = new CookieContainer();
                hwr.CookieContainer = cc;
                HttpWebResponse hwrs = (HttpWebResponse)hwr.GetResponse();
                Stream myStream = hwrs.GetResponseStream();
                Encoding encoding = Encoding.GetEncoding(encodeType);
                StreamReader sr = new StreamReader(myStream, encoding);
                strResult = sr.ReadToEnd();
                hwrs.Close();
            }catch{
                strResult = "wrong";
            }return strResult;
        }
string xmlStr = Common.Get_HttpAll("http://typhoon.weather.gov.cn/Typhoon/data/20130041.xml", "utf-8");


獲取結果和上個方法一樣是少了兩個節點。

這該怎么辦呢?使出必殺技!!!


3.選擇使用了Webbrowser類去獲取數據,核心代碼如下
利用Webbrowser加載文檔完畢后的狀態進行判斷然后獲取文檔):

 private void Delay(int Millisecond)
        {
            DateTime current = DateTime.Now;while (current.AddMilliseconds(Millisecond) > DateTime.Now)
            {
                Application.DoEvents();
            }return;
        }

WebBrowser wb = new WebBrowser();string xmlStr = string.Empty;
wb.Navigate("http://typhoon.weather.gov.cn/Typhoon/" + dataUrl);while (true)
                {
                    Delay(50);//延遲50毫秒if (wb.ReadyState == WebBrowserReadyState.Complete)//判斷文檔是否加載完畢
                    {if (!wb.IsBusy)
                        {
                            xmlStr = wb.Document.Body.InnerText;break;
                        }
                    }continue;
                }


注:在獲取網頁數據的時候,會存在頁面或頁面部分內容是異步加載的情況,這時候通過常用的請求數據方法可能會不完整,這個時候就可以選擇使用webbrowser。

      在這個問題中選擇webbrowser也是不得已的辦法,如果哪位園友有其他高見,望不吝賜教!



正在看本人博客的這位童鞋,我看你氣度不凡,談吐間隱隱有王者之氣,日后必有一番作為!旁邊有推薦二字,你就順手把它點了吧,相得準,我分文不收;相不準,你也好回來找我!

      


Cnblogs 施瓦小辛格 2015-08-23 08:57:29

[新一篇] 使用Inno Setup 打包.NET程序,并自動安裝.Net Framework - 小剛qq

[舊一篇] .NET開發者需要的工具箱
回頂部
寫評論


評論集


暫無評論。

稱謂:

内容:

驗證:


返回列表