腰痠推薦Java-Jsoup爬取妹子圖
日常求贊,感謝老闆。
歡迎關注公衆號:其實是白羊。乾貨持續更新中…
一、先放成果
保存到本地的圖我就不放了,審覈過不了
我扶了下腰,不多不多。。。
二、前言背景
之前一直聽爬蟲爬蟲的,咱也不知道是啥,但都是用Python,咱也不會啊,就會個Java。後來瞭解到,簡單的爬蟲其實就是解析頁面嘛,提取自己需要的資源(嘿嘿)。再後來在工作中接到了個需求裏需要解析html,度娘了一下了解到了Jsoup這個類庫。需求做完了,就這麼結束?怎麼可能,當然是做一些有趣的事情啦。
- 先確定目標:練習爲主選取比較容易搞的圖片,於是我找到了這個妹子圖
- 半小時過後,我開始了制定計劃,爬取網站獲取alt做名字,獲取連接存到數據庫裏,以備不時之需。
三、實現過程
一)引入依賴
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.12.1</version>
</dependency>
二)瞭解類庫
主要方法都在Jsoup類提供的靜態方法:
-
String html = "<html><head><title>First parse</title></head>" + "<body><p>Parsed HTML into a doc.</p></body></html>"; Document doc = Jsoup.parse(html);//通過Document可以獲取裏面的任何值 //html必須是html哦不能是片段
-
String html = "<div><p>Lorem ipsum.</p>"; Document doc = Jsoup.parseBodyFragment(html);//解析html片段,封裝成完整的html Element body = doc.body();//獲取其中的body片段
-
重頭戲來了
Connection connect = Jsoup.connect("http://example.com/");//獲取Connection Document document = connect.get();//Connection可以設置常規網絡請求都可以設置的一些項,如: //connect.header("Accept-Encoding", "gzip, deflate, sdch");//設置請求頭(注意要在調用get或post方法之前設置) //connect.cookie("auth", "token");//設置cookie //connect.timeout(3000);//設置響應時間等 //這是爬取資源重要的一步哦 String title = document.title();
下面是對於Document解析想要的值的方法:
查找元素
getElementById(String id)
getElementsByTag(String tag)
getElementsByClass(String className)
getElementsByAttribute(String key)
(and related methods)- Element siblings:
siblingElements()
,firstElementSibling()
,lastElementSibling()
;nextElementSibling()
,previousElementSibling()
- Graph:
parent()
,children()
,child(int index)
元素數據
attr(String key)
獲取屬性attr(String key, String value)
設置屬性attributes()
獲取所有屬性id()
,className()
andclassNames()
text()
獲取文本內容text(String value)
設置文本內容html()
獲取元素內HTMLhtml(String value)
設置元素內的HTML內容outerHtml()
獲取元素外HTML內容data()
獲取數據內容(例如:script和style標籤)tag()
andtagName()
操作HTML和文本
append(String html)
,prepend(String html)
appendText(String text)
,prependText(String text)
appendElement(String tagName)
,prependElement(String tagName)
html(String value)
以上內容參考自:更多方法使用
三)給爺爬
瞭解了類庫,我們就可以着手開始實踐解析了:
-
先分析下網站上的資源都在哪?
String url = "https://www.mzitu.com/page/1/"; Connection connect = Jsoup.connect(url); Document document = connect.get();
我們可以看到得到的document中我們想要的資源是這樣存在的:
<img class="lazy" src="https://www.mzitu.com/static/pc/img/lazy.png" data-original="https://i.mmzztt.com/thumb/2020/04/226719_236.jpg" alt="不可描述、過不了審" width="236" height="354">
ok,那麼我們要的是img標籤下data-original屬性的值和alt屬性的值。
-
解析獲取
//在上面代碼基礎上 Elements imgs = document.getElementsByTag("img");//獲取全部img for (Element img : imgs) { String src = img.attr("data-original"); String alt = img.attr("alt"); log.info("第{}頁:alt->{};src->{}", i, alt, src); }
到這就ok啦,alt是圖片的描述可以將它作爲圖片的名字,src就是圖片的請求地址,你可以直接將它存在數據庫裏,或者直接保存到本地磁盤(具體做法後面會寫)
-
接這樣結束了?怎麼可能這可是有243頁哎(再深的咱們就不挖了)。看下不同頁的url可以寫成:
for (int i = 1; i <= 243; i++) { String url = "https://www.mzitu.com/page/"+ i +"/"; //獲取+解析步驟省略參考上面步驟 }
-
執行下來你會發現,保存下來的圖片後面很多都是,這個:
不同的url請求下來的卻是同一張圖片,單獨把url拿出來請求下,果然是請求了只有重定向到了這個圖片。嗯雖然我不知道他具體是怎麼做的,但我猜應該是從什麼地方判斷出我不是正常請求,或者是判斷同一個ip請求的頻率,之後就把我的每次請求都重定向到了這個圖片導致我有url卻看不到我想要的東西,可惡。
既然他能判斷出我不是正常請求,那我們就看看正常請求和直接訪問請求有什麼區別吧:
正常瀏覽:
url直接請求:
發現什麼沒,請求頭裏少了Referer,找到原因了那就試一哈。
-
多次正常瀏覽後,總結髮現Referer的值是上一次瀏覽的url
-
綜上在使用Jsoup時獲取網頁和根據url請求資源時加上一定的請求頭:
//簡單寫下意思(文末會賦源碼) for (int i = 1; i <= 243; i++) { String url = "https://www.mzitu.com/page/" + i + "/"; Connection connect = Jsoup.connect(url); connect.header("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"); connect.header("Accept-Encoding", "gzip, deflate, sdch"); connect.header("Accept-Language", "zh-CN,zh;q=0.8"); connect.header("Sec-Fetch-Dest", "document"); connect.header("Upgrade-Insecure-Requests", "1"); connect.header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36"); connect.header("Referer", refererPageInit); Document document = connect.get(); //todo 解析出需要的資源 refererPageInit = "https://www.mzitu.com/page/" + i + "/"; }
至此你就能獲取這兩百多頁(六七千多張圖片)啦。
四、最後
各位紳士先放下手中的針線活,源碼在此,覺得寫的還可以的給點個贊,也可以評論瀏覽討論下。
更多資源:其實是白羊
歡迎star
日常求贊
- 如果你認爲本文對你有幫助,還請「在看/轉發/贊/star」,多謝
- 如果你還發現了更好或不同的想法,還請在留言區不吝賜教,一起探討交流修改,萬分感謝
歡迎關注公衆號:「其實是白羊」乾貨持續更新中…