C# 爬取網頁上的數據


       最近工作中需求定時爬取不同城市每天的溫度。其實就是通過編程的方法去抓取不同網站網頁進行分析篩選的過程。.NET提供了很多類去訪問並獲得遠程網頁的數據,比如WebClient類和HttpWebRequest類。這些類對於利用HTTP去訪問遠端的網頁並且下載下來是很有用的,但在對於所下載下來的HTML的解析能力方面,則顯得功能很弱了。推薦一個開源的組件HTML Agility Pack(http://htmlagilitypack.codeplex.com/),它的設計目標是盡可能簡化對HTML文檔的讀和寫。這個包本身是利用了DOM文檔對象模型去解析HTML的。在此順便記錄一下最近收集的爬取歷史和當前天氣的網站備用:

中國天氣網(Weather.com.cn)


  • 該網提供有如下三個Json格式的查詢接口,以北京為例:
  • http://www.weather.com.cn/data/sk/101010100.html
  • http://www.weather.com.cn/data/cityinfo/101010100.html
  • http://m.weather.com.cn/data/101010100.html
  • ID是一個9位的數字,按照長度可以分為如下四部分:101(國家代號) 01(省) 01(二級地區) 00(三級地區)
  • 要獲取所有的地區代號,通過如下方式:https://wqbot.blob.core.windows.net/botdemo/CityCode.xml

示例Demo


      編程使用示例如下:我們要獲取如下網頁中的天氣信息:

    

     下載HTML Agility Pack組件,新建控制台程序,在你的工程中引用相應framework版本對應的組件,示例代碼如下:        

            string url = @"http://lishi.tianqi.com/beijing/201701.html";
            var webGet = new HtmlWeb();
            var document = webGet.Load(url);
            var div = document.DocumentNode.SelectNodes("//div[@class='tqtongji2']/ul");
            foreach (HtmlNode node in div)
            {
                var tmpNode = node.SelectNodes("li");
                Console.WriteLine(string.Format("{0}-----------{1}---------{2}----------{3}",
                    tmpNode[0].InnerText,
                    tmpNode[1].InnerText,
                    tmpNode[2].InnerText,
                    tmpNode[3].InnerText));
            }
            Console.ReadKey();

程序運行效果:中文存在亂碼,如下圖

通過分析HTML Agility Pack源碼,在HtmlWeb類的Get(Uri uri, string method, string path, HtmlDocument doc)方法中,局部變量 resp是http請求的response。設置斷點發現resp.ContentEncoding為空。因此通過HttpWebRequest來下載數據,示例代碼如下:

            string url = @"http://lishi.tianqi.com/beijing/201701.html";
            HttpWebRequest req = WebRequest.Create(new Uri(url)) as HttpWebRequest;
            req.Method = "GET";
            WebResponse rs = req.GetResponse();
            Stream rss = rs.GetResponseStream();
            HtmlDocument doc = new HtmlDocument();
            doc.Load(rss);
            var div = doc.DocumentNode.SelectNodes("//div[@class='tqtongji2']/ul");
            foreach (HtmlNode node in div)
            {
                var tmpNode = node.SelectNodes("li");
                Console.WriteLine(string.Format("{0}-----------{1}---------{2}----------{3}",
                    tmpNode[0].InnerText,
                    tmpNode[1].InnerText,
                    tmpNode[2].InnerText,
                    tmpNode[3].InnerText));
            }
            Console.ReadKey();

代碼運行效果如下:

 

 that's ok!!!

 

  

 

 

   


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM