網上有不少Python爬蟲的帖子,不排除不少培訓班藉着AI的概念教Python,而後爬網頁天然是其中的一個大章節,畢竟作算法分析沒有大量的數據怎麼成。程序員
C#相比Python可能笨重了些,但實現簡單爬蟲也很便捷。網上有很多爬蟲工具,經過配置便可實現對某站點內容的抓取,出於定製化的需求以及程序員重複造輪子的習性,我也作了幾個標準公開網站的爬蟲。web
在學習的過程當中,爬網頁的難度愈來愈大,但隨着問題的一一攻克,學習到的東西也愈來愈多,從最初簡單的GET,到POST,再到模擬瀏覽器填寫表單、提交表單,數據解析也從最初的字符串處理、正則表達式處理,到HTML解析。一個NB的爬蟲須要掌握的知識很多,HTTP請求、響應,HTML DOM解析,正則表達式匹配內容,多線程、數據庫存儲,甚至有些高級驗證碼的處理都得AI。正則表達式
固然,爬爬公開標準不是那麼難,好比國家標準全文公開系統。算法
整個過程須要爬如下頁面:sql
須要處理的技術問題有:數據庫
首先查看到標準分GB和GB/T兩類,地址分別爲:瀏覽器
http://www.gb688.cn/bzgk/gb/std_list_type?p.p1=1&p.p90=circulation_date&p.p91=desc服務器
和多線程
http://www.gb688.cn/bzgk/gb/std_list_type?p.p1=2&p.p90=circulation_date&p.p91=desc。ide
從中能夠看出,GET請求的查詢字符串參數p1值爲1和2分別查詢到GB和GB/T。所以,要獲取到標準列表,向以上地址發送GET請求便可。
HttpWebRequest httprequst = (HttpWebRequest)WebRequest.Create(Url); HttpWebResponse webRes = (HttpWebResponse)httprequst.GetResponse(); using (System.IO.Stream stream = webRes.GetResponseStream()) { using (System.IO.StreamReader reader = new StreamReader(stream, System.Text.Encoding.GetEncoding("utf-8"))) { content = reader.ReadToEnd(); } }
標準共N多頁,查看第二頁標準列表,地址更改成:
http://www.gb688.cn/bzgk/gb/std_list_type?r=0.7783908698326173&page=2&pageSize=10&p.p1=1&p.p90=circulation_date&p.p91=desc。
因而可知page參數指定了分頁列表的當前頁數,據此,循環請求便可獲取到全部的標準列表信息。
獲取到標準列表後,下一步我須要獲取到標準的詳細信息頁,從詳細信息頁中抓取更多的標準說明信息,例如標準的發佈單位、歸口單位等。
查看標準詳細頁URL,其值爲:
http://www.gb688.cn/bzgk/gb/newGbInfo?hcno=9E5467EA1922E8342AF5F180319F34A0。
能夠看出每一個標準有個GUID值,在列表頁面中點擊按鈕「查看詳細」,轉到詳細頁。實現這個跳轉的方式,最簡單的是HTML超連接,此外還能夠是JS腳本,甚至是POST數據到服務器。不一樣的連接方式,天然須要不一樣的抓取方式,所以須要查看列表頁源碼來分析該站點的實現方式並找到對應的處理方法。
經過分析源碼,能夠看到在點擊標準號時,經過JS的showInfo函數打開詳細頁面,因爲JS方法傳遞的ID即爲詳細頁面的參數ID,所以不必去模擬onclick執行JS函數,直接解析到該GUID,GET請求詳細頁面便可。解析該GUID值,能夠經過正則表達式方便的抓取到。
獲取到詳細信息頁面後,要解析其中的內容,此時使用正則表達式解析就比較費勁了,能夠採用HTML解析。C#解析HTML的第三方類庫有很多,選擇其中一款便可,HtmlAgilityPack或Winista.HtmlParser都是比較好用的。
解析到標準詳細信息後,還須要進一步獲取到標準PDF文件,分析詳細頁面能夠看到標準文件下載頁面路徑爲:
http://c.gb688.cn/bzgk/gb/showGb?type=download&hcno=9E5467EA1922E8342AF5F180319F34A0
進一步分析PDF文件的URL爲:
http://c.gb688.cn/bzgk/gb/viewGb?hcno=9E5467EA1922E8342AF5F180319F34A0。
仍然是那個GUID值,所以能夠直接GET請求該地址便可下載標準PDF文件。
至此標準的屬性信息和標準PDF文件均可如下載到了,而後須要將這些信息存儲起來。存儲爲SQL Server、Oracle天然比較笨重,即便Excel和Access也不大友好,推薦此類臨時存儲可使用SqlLite。
string connectionString = @"Data Source=" + dbBasePath + "StandardDB.db;Version=3;"; m_dbConnection = new SQLiteConnection(connectionString); m_dbConnection.Open(); SQLiteCommand command = new SQLiteCommand(sql, m_dbConnection); command.ExecuteNonQuery(); m_dbConnection.Close();