[爬蟲進階]使用Jsoup取代你的一切網絡請求方法(java,post,get,代理IP)
原文鏈接:https://www.cnblogs.com/blog5277/p/9334560.html
原文作者:博客園--曲高終和寡
*******************如果你看到這一行,說明爬蟲在本人還沒有發布完成的時候就抓走了我的文章,導致內容不完整,請去上述的原文鏈接查看原文****************
爬蟲最近似乎越來越火了,隨着各個培訓班開啟了各種課程,似乎用用Python里的XX框架,就能抓天抓地抓空氣了
真的是這樣么?
嘻嘻嘻,當然不是了,爬蟲不是Python專屬,同樣,數據采集,數據清洗,AI,機器學習,都不是,語言只是工具,底層都是數學,Python有的工具java和java系的基本都有
扯遠了,這里只說爬蟲好了,我看了看網上那些教程,大多數都是講這個網站怎么獲取里面的數據,把網址,解析規則自己分析一下調個方法就運行了.
重要不重要,重要,但是寫爬蟲的最麻煩的不是這個.
上面這東西說白了,任何能請求到一個頁面源碼的方法+DOM結構解析器,都能做.(當然,人家也是面對新手的教程)
當你在工作中使用爬蟲的時候,你會遇到如下問題:
1.網站的反爬蟲機制(驗證碼,封IP,投毒,js動態渲染頁面)
2.分布式爬蟲的效率與去重
但是基本上講,只要是web瀏覽器上能打開的數據,你都能爬到,因為我們只要盡量模擬真人的操作就行了唄,反爬蟲手段只是提升了爬蟲的成本,不可能杜絕爬蟲的,因為這樣一定會誤傷很多真人用戶.
更多的就不細講了,有點跑題,我在爬蟲(或者高大上點叫數據挖掘?)上還有很多的路要走,參考別的大神的思路.
又扯遠了,回歸主題,介紹Jsoup
身為開發人員,你一定會有很多時候要發起網絡請求,比如各個第三方API,比如寫爬蟲,那么你一定會遇到很多問題:
網站編碼是utf-8,還是GBK,GB2312或者更奇葩的編碼,
網站是否是GZIP壓縮,
post還是get
post的參數要用raw形式放在request body里面
每種情況你用httpclient也好,還是httpconnect也好,都要不同情況單獨處理,很麻煩,你要是寫個通用爬蟲框架,一下子爬幾百個網站,那難道說每個網站都要單獨設置一下?
我們只想要輸入一個連接,輸入參數,就能返回內容的方法,難道就這么難么?
是的,挺麻煩的,直到我遇到了jsoup
1.引入依賴,maven
<!-- https://mvnrepository.com/artifact/org.jsoup/jsoup --> <dependency> <groupId>org.jsoup</groupId> <artifactId>jsoup</artifactId> <version>1.11.3</version> </dependency>
百度谷歌"jsoup maven",個人推薦用最新的,時刻追上發展的腳步嘛
2.發送get請求
3.發送post請求
是的,就是這么簡單,再也不用管編碼,再也不用管GZIP了,你敢發,jsoup就能解析好返回給你.
4.發送post,帶參數
要么多.幾個data,要么傳個map,最后.post();
5,發送post,帶requestbody
6,設置超時(個人建議必設)
7,設置動態代理IP,再配合你自己寫一個代理的IP池,就可以防止反爬蟲封你的IP了
8,設置cookie
9,設置瀏覽器
10,設置各種header
好了,不談了,更多的你們自己點一點看一看,非常的容易,另外我個人建議
.ignoreContentType(true).ignoreHttpErrors(true)
這倆一定要開啟
細心的朋友一定發現了,返回值是Document
那么怎么返回String類型的html源碼呢,直接在get(),或者post()后面這樣就行了
如果是調的接口,返回值是json,或者你只需要返回不帶html標簽的正文,那么這樣就可以了
記得隨時trim的好習慣哦.
這里放兩個我自己常用的get和post通用的方法吧
public static Document getJsoupDocGet(String url) { //三次試錯 final int MAX = 10; int time = 0; Document doc = null; while (time < MAX) { try { doc = Jsoup .connect(url) .ignoreContentType(true) .ignoreHttpErrors(true) .timeout(1000 * 30) .userAgent("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36") .header("accept","text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8") .header("accept-encoding","gzip, deflate, br") .header("accept-language","zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7") .get(); return doc; } catch (Exception e) { e.printStackTrace(); } finally { time++; } } return doc; } public static Document getJsoupDocPost(String url, Map<String,String> paramMap) { //三次試錯 final int MAX = 10; int time = 0; Document doc = null; while (time < MAX) { try { doc = Jsoup .connect(url) .ignoreContentType(true) .ignoreHttpErrors(true) .timeout(1000 * 30) .userAgent("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36") .header("accept","text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8") .header("accept-encoding","gzip, deflate, br") .header("accept-language","zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7") .data(paramMap) .post(); return doc; } catch (Exception e) { e.printStackTrace(); } finally { time++; } } return doc; }
其實返回值Document還有更加強大的作用,它是個DOM解析器,我寫爬蟲全用它,具體怎么實現的,請自己去
https://www.jsoup.org/
學習,然后去
https://try.jsoup.org/
實驗,(建議直接復制源碼進來,不要用這里面自帶的fetch)
我這里就不談了,真的好用