我好久沒來csdn寫文章了,為什麼呢?說句實話,其實不是自己不來寫文章了,而是自己太關注形式化的東西了,有一段時間把文章寫在github上面,感覺有自己的站點很特殊,很與衆不同。其實用github來寫文章确實是很不錯的,使用mackdown标記語言給人一種高效編寫的感覺。是以打算好好利用這兩個平台,csdn的簡潔性,可以讓自己在使用windows系統時寫一寫技術文章同時很好地與他人進行評論交流。在使用linux系統時,可以利用終端的特性,使用git,寫一寫部落格。行了,自己不在糾結了,就這麼定了。程式設計練習固然重要,但是不總結也難以有收獲。隻希望把自己所遇、所悟、所感都記錄成文字,這樣一步一步積累,最終希望自己有一個質的蛻變。
————————————————————————————————————————————————————
下面介紹webmagic爬蟲,爬取拉勾網的職位資訊。
第一步:利用chrome和火狐檢查連結
檢視連結後,我們檢查元素會發現這個連結不是我們需要的,因為類似于這種網站,資料的傳輸都是利用ajax的,是以進行第二步。
第二步:啟用chrome調試,抓包分析
點選xhr(XmlHttpRequrest)F12後,可以看見以上ajax連結,從名字便可以看出來,第一個便是我們所需要的職位資訊,點選連結檢視詳細資訊。
如上圖所示,request-header資訊全部顯示在右側,這個資訊至關重要,因為這是你能夠通路這個連結的重要認證。下面看一下此連結所傳輸的資料,點選Preview如下圖所示:
所有的職位資訊都在這了,當然這也是固定頁的職位資訊,當頁數不一樣時,傳遞的職位資訊不一樣,這個需要考慮到post請求,後面會講到。好,接下來,正式爬取。請看代碼
private Site site = Site.me()
.setRetryTimes(3)
.setSleepTime(1000)
.addHeader("Accept","application/json, text/javascript, */*; q=0.01")
.addHeader("Accept-Encoding","gzip, deflate, br")
.addHeader("Accept-Language","zh-CN,zh;q=0.8")
.addHeader("Connection","keep-alive")
//.addHeader("Content-Length","23")
.addHeader("Content-Type","application/x-www-form-urlencoded; charset=UTF-8")
.addHeader("Cookie","Hm_lvt_4233e74dff0ae5bd0a3d81c6ccf756e6=1516684224,1516688332,1516708458,1517989813; _ga=GA1.2.803780703.1515996477; user_trace_token=20180115140756-6e315eee-f9ba-11e7-a353-5254005c3644; LGUID=20180115140756-6e316229-f9ba-11e7-a353-5254005c3644; index_location_city=%E5%85%A8%E5%9B%BD; JSESSIONID=ABAAABAAADEAAFI7B8A950147564B82F61A115D162E1281; LGSID=20180207155015-888d0972-0bdb-11e8-bdd2-525400f775ce; LGRID=20180207163606-f07d2f3d-0be1-11e8-af98-5254005c3644; Hm_lpvt_4233e74dff0ae5bd0a3d81c6ccf756e6=1517992563; TG-TRACK-CODE=index_navigation; SEARCH_ID=ada31aea74d74f0ba5625adf851d1c6f; X_HTTP_TOKEN=4235610f3926fcdc9a4b942f0c350399; _putrc=0DA9DA012C722A8E; login=true; unick=%E7%8E%8B%E5%86%B6; showExpriedIndex=1; showExpriedCompanyHome=1; showExpriedMyPublish=1; hasDeliver=0; gate_login_token=fc49718b5340e22bfe7adebb2937015b765f94906d1f154c; _gat=1")
.addHeader("Host","www.lagou.com")
.addHeader("Origin","https://www.lagou.com")
.addHeader("Referer","https://www.lagou.com/jobs/list_Java")
.addHeader("User-Agent","-Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3095.5 Mobile Safari/537.36")
.addHeader("X-Anit-Forge-Code","0")
.addHeader("X-Anit-Forge-Token","None")
.addHeader("X-Requested-With","XMLHttpRequest");
這段代碼,熟悉webmagic可以迅速看懂,設定site,這裡建議大家寫成這樣,可以清楚地看出自己哪些請求頭參數沒有填寫,重點講解一下:
1.Cookie : 其實cookie便是模拟登陸的簡單實作,也可以通過發送post請求,實作登入。請記住,此處的cookie一定是你登入後浏覽這一頁的時候的cookie
2.User-Agent :使用者代理,這個并不是IP代理,而是一般網站的反爬機制。
3.Referer:這個東西是拉鈎網目前為止的反爬機制,其實這個标記,它代表這你通路目前連結的上一個連結,就是你是在A頁面點選跳轉到B頁面,那麼B頁面的Referer便是A連結。檢視後,你會發現目前頁面的referer連結為:
https://www.lagou.com/jobs/list_Java?px=default&city=%E5%8C%97%E4%BA%AC
你可能會問這麼多參數,萬一變化怎麼辦,其實都是騙人的,我們打開火狐浏覽器檢驗一下:
點選編輯和重發
重新填寫請求,将referer的連結參數去掉:
點選發送請求,檢視顯示JSON資訊,可以看到,傳回的JSON資訊完全一樣,可見參數不會影響。
4. Content-Length:可以看到這個屬性注釋掉了,為什麼?請看google給出的解釋:
content length是指報頭以外的内容長度。 一般的伺服器實作中,超過這個長度的内容将被抛棄。 不會産生新post。 如果短于内容長度,協定要求伺服器傳回400錯誤資訊Bad Request(不正确的請求)的。
是以,一定要注釋掉!
第三步:簡單爬取JSON資料:
public void process(Page page)
{
// this.processBeiJing(page);
// this.processTianJin(page);
page.putField("position",new JsonPathSelector("$.content.positionResult.result[*].positionName").selectList(page.getRawText()));
}
public static void main(String []argv)
{
Spider.create(new LaGouSpider())
.addUrl("https://www.lagou.com/jobs/positionAjax.json?px=default&city=北京&needAddtionalResult=false&isSchoolJob=0")
.thread(2)
.run();
}
寫到這裡,可以看出,爬蟲重在分析!爬蟲截圖如下:
接下來,講述一下發送post請求擷取,分頁的職位資訊:
可以看到,這個頁面共有30頁,那每一頁的連結又是怎麼來的呢?請看下圖:
可以看到,first表示是否初次通路頁面,pn表示頁号,kd是關鍵字。那好了,我們隻需要模拟發送30post請求,便可擷取到不同頁面的JSON資訊。并且,webmagic提供了很好地POST方法,詳情請看webmagic文檔。代碼如下:
public void processBeiJing(Page page)
{
if(flag==0)
{
Request [] requests = new Request[3];
Map<String,Object> map = new HashMap<String, Object>();
for(int i=0;i<requests.length;i++)
{
requests[i] = new Request("https://www.lagou.com/jobs/positionAjax.json?px=default&city=北京&needAddtionalResult=false&isSchoolJob=0");
requests[i].setMethod(HttpConstant.Method.POST);
if(i==0)
{
map.put("first","true");
map.put("pn",i+1);
map.put("kd","java");
requests[i].setRequestBody(HttpRequestBody.form(map,"utf-8"));
page.addTargetRequest(requests[i]);
}
else
{
map.put("first","false");
map.put("pn",i+1);
map.put("kd","java");
requests[i].setRequestBody(HttpRequestBody.form(map,"utf-8"));
page.addTargetRequest(requests[i]);
}
}
flag++;
}
}
感覺代碼還算清晰,稍做解釋:
flag是标記,因為webmagic的post方法,隊列中是不做去重處理的,也就是說,add方法沒有辦法檢驗隊列中是否含有post請求,故會一直循環加入,無法停止。
好了,利用以上代碼,便可怕取到1-30頁的JSON資訊。截圖如下:
ok了,截止到現在,所有的步驟都已經講解完成。代碼檔案已經上傳至github點選打開連結(附帶開源中國爬蟲和哔哩哔哩視訊爬蟲源碼),大家有問題可以留言交流,一起學習。
QQ:3091485316
微信:wangye889905
個人技術微信公衆号: