倔强的网站数据抓取,关键时刻还需Webbrowser显身手_.NET_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > .NET > 倔强的网站数据抓取,关键时刻还需Webbrowser显身手

倔强的网站数据抓取,关键时刻还需Webbrowser显身手

 2013/10/22 14:55:28  艾编程  博客园  我要评论(0)
  • 摘要:由于最近台风挺多,公司网站上需要挂上台风预报信息,就整了个抓取台风数据(至于抓数据的概念和实践手册我以前写的一篇博客里面有介绍:分享一套抓数据小程序,客户资料、实时新闻、股票数据…随心抓)的服务,做调试阶段,发现个诡异的问题。如下:需要抓取的数据是个xml文件,地址如下:http://typhoon.weather.gov.cn/Typhoon/data/20130041.xml,这是政府气象网发布的最近某个台风的数据信息,具体代表什么意思不是本文研究的范畴,有兴趣的可以研究研究
  • 标签:Web 数据 网站 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>

class="webkit-html-tag">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也是不得已的办法,如果哪位园友有其他高见,望不吝赐教!

正在看本人博客的这位童鞋,我看你气度不凡,谈吐间隐隐有王者之气,日后必有一番作为!旁边有“推荐”二字,你就顺手把它点了吧,相得准,我分文不收;相不准,你也好回来找我!

      

发表评论
用户名: 匿名