—本博客為原創內容,轉載需注明本人—
前幾天有個師妹將要畢業,需要准備畢業論文,但是論文調研需要數據資料,上知網一查,十幾萬條數據!指導老師讓她手動copy收集,十幾萬的數據手動copy要浪費多少時間啊,然后她就找我幫忙。我想了一下,寫個爬蟲程序去爬下來或許是個不錯的解決方案呢!之前一直聽其他人說爬蟲最好用python,但是我是一名Java工程師啊!魯迅曾說過,學python救不了中國人,但是Java可以!
好啦,開個玩笑,主要是她急着要,我單獨學一門語言去做爬蟲,有點不現實,然后我就用了Java,去知乎看一下,發現原來Java也有很多開源的爬蟲api嘛,然后就是開始干了,三天時間寫好程序,可以爬數據下來,下面分享一下技術總結,感興趣的朋友可以一起交流一下!
在分享技術之前,先簡單說一下爬蟲的原理吧。網絡爬蟲聽起來很高大上,其實就是原理很簡單,說的通俗一點就是,程序向指定連接發出請求,服務器返回完整的html回來,程序拿到這個html之后就進行解析,解析的原理就是定位html元素,然后將你想要的數據拿下來。
那再看一下Java開源的爬蟲API,挺多的,具體可以點擊鏈接看一下:推薦一些優秀的開源Java爬蟲項目
因為我不是要在實際的項目中應用,所以我選擇非常輕量級易上手的 crawler4j 。感興趣的可以去github看看它的介紹,我這邊簡單介紹一下怎么應用。用起來非常簡單,現在maven導入依賴。
自定義爬蟲類繼承插件的WebCrawler類,然后重寫里面shouldVisit和Visit方法。
然后定義一個Controller來執行你的爬蟲類
直接運行main方法,你的第一個爬蟲程序就完成了,非常容易上手。
那接下來我們說一下程序的應用,我需要抓取中國知網上2016-2017兩年的中國專利數據。
那么說一下這個應用的幾個難點。
1.知網的接口使用asp.net做的,每次請求接口都要傳當前的cookies,接口不直接返回數據,而是返回HTML界面
2.數據量過於龐大,而且需要爬取的是動態資源數據,需要輸入條件檢索之后,才能有數據
3.數據檢索是內部用js進行跳轉,直接訪問鏈接沒有數據出來
4.這個是最難的,知網做了反爬蟲設置,當點擊了15次下一頁之后,網頁提示輸入驗證碼,才能繼續下一頁的操作
那接下來就根據以上的難點來一步一步的想解決方案吧。
首先就是數據檢索是內部用js進行跳轉,直接訪問鏈接沒有數據出來,這就表示上面的crawler4j沒有用了,因為他是直接訪問連接去拿html代碼然后解析拿數據的。然后我再網上查了一下資料,發現Java有一個HtmlUtil。他相當於一個Java的瀏覽器,這簡直是一個神器啊,訪問到網頁之后還能對返回來的網頁進行操作,我用個工具類來創建它
有了這個HtmlUtil,基本已經解決了大部分問題,我這里的操作邏輯是先用HtmlUtil訪問知網,然后用定位器找到條件,輸入搜索條件,然后點擊檢索按鈕,用Java程序模擬人在瀏覽器的操作。
上述代碼的thirdPage就是最終有數據的html頁面。
那下面就是爬蟲最關鍵的一個地方,解析爬下來的html代碼,分析html代碼的話,我就不在這里分析,html基礎不好的朋友可以去w3cshool補一下,我這里直接說HtmlUtil定位html元素的的方法吧。上面的代碼可以看到HtmlUtil可以通過value,text,id,name定位元素,如果上面這些都定位不了元素的話,那就使用Xpath來定位。
那拿到列表數據之后呢,我就用HtmlUtil一個個點擊進去,進去專利的詳情頁。
這里面的專利名,申請日期,申請人和地址就是我要爬的數據,因為詳情頁的html比較復雜,我使用了Java一個比較好用的html解析器jsoup
解析完之后呢,將數據封裝到對象里,然后將對象存在一個List里,全部數據解析完之后,就把數據導出的csv文件中。
這樣爬蟲程序就基本寫好了,運行一下發現效率太慢了,爬一頁列表的數據加導出,花了1分多鍾,然后我優化了一下程序,將解析和導出業務邏輯開一條線程來做,主線程負責操作HtmlUtil和返回Html。
現在再跑程序,速度快了一點,也能把數據爬下來了,項目源碼可以在我的github下載:項目源碼,感興趣的同學可以下載來跑一下。有問題的可以在評論區交流,小弟我沒什么經驗,如果有什么問題還請指出,大家一起交流。
現在還有個難點沒有解決就是知網的驗證碼驗證,我這邊想到的一個笨方法是縮小搜索范圍,減少數據量從而減少點擊下一頁的次數來跳過驗證碼驗證,不過這個需要手動改條件,重復跑很多次程序,如果有大佬有好的解決方案也可提出來。謝謝啦!