談拉鉤網(wǎng)爬蟲的源碼分析、爬蟲策略及問題解決
</br>
拉鉤網(wǎng)因其json格式的結(jié)構(gòu)化數(shù)據(jù),
成為幾乎所有“爬者”必經(jīng)的練手場(chǎng)。
網(wǎng)上許多高手也分享了他們的經(jīng)驗(yàn)和代碼。
上一篇我們簡(jiǎn)單分析和展示了數(shù)據(jù)。
今天分幾塊來深入剖析拉鉤網(wǎng)爬蟲。
</br>
一、一般爬取策略
多說無益,以圖為例,簡(jiǎn)要分析~










已經(jīng)盡量解析的詳細(xì)了,
一般爬取思路大概就是這樣。
</br>
二 、爬蟲新思路
上面我們談了一般思路,相信很多爬友早就發(fā)現(xiàn)了。然而拉勾網(wǎng)的爬蟲實(shí)在太多了,其反爬機(jī)制經(jīng)常變動(dòng),爬取難度逐漸增加。
這一回我用上面的方法,結(jié)果返回這樣:

懵了。
最初以為是user_agent等問題,又設(shè)隨機(jī)數(shù)還是不見好。估計(jì)是拉鉤修改了反爬機(jī)制。
試著模擬登錄,然而,F(xiàn)orm采用復(fù)雜的
暗文密碼,成功嚇退小白。
最后重新構(gòu)造URL,get方式解決
那我是怎么做到的呢?
最初是盯著network發(fā)呆,后面留意到URL后面的needAddtionalResult=false
'needAdditionalResult',額外添加?好吧,那就隨便加點(diǎn)東西。加什么好呢?


那就隨便這個(gè)好咯,然后返回這樣

直接構(gòu)造URL,哈哈我簡(jiǎn)直聰明~ (_)!
純屬瞎撞,第二天想到onenote中一筆記:

我們用form提交的表單,其實(shí)最終會(huì)變成上面那樣的格式。(用不用post基本差不多)
get方式獲取數(shù)據(jù),加個(gè)cookies即可。
代碼如下,還是放個(gè)完整版:
# !usr/bin/env python
# --coding:utf-8 --
author='WYY'
date='2017.03.29'
#實(shí)戰(zhàn)小項(xiàng)目:爬取拉鉤網(wǎng)并作小型數(shù)據(jù)分析
import requests
import json
import xlwt
import time
import random
class Spider():
def __init__(self):
self.keyword=raw_input(u'請(qǐng)輸入職位:')
#獲取數(shù)據(jù)
def getData(self,url):
user_agents=['Mozilla/5.0 (Windows NT 6.1; WOW64; rv:23.0) Gecko/20130406 Firefox/23.0',
'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:18.0) Gecko/20100101 Firefox/18.0',
'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/533+ \(KHTML, like Gecko) Element Browser 5.0',
'IBM WebExplorer /v0.94', 'Galaxy/1.0 [en] (Mac OS X 10.5.6; U; en)',
'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)',
'Opera/9.80 (Windows NT 6.0) Presto/2.12.388 Version/12.14',
'Mozilla/5.0 (iPad; CPU OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) \Version/6.0 Mobile/10A5355d Safari/8536.25',
'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) \Chrome/28.0.1468.0 Safari/537.36',
'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.0; Trident/5.0; TheWorld)']
index=random.randint(0, 9)
user_agent=user_agents[index]
headers={'User_agent':user_agent,
'cookie':'user_trace_token=20170328171202-9af479cf-1396-11e7-a59b-525400f775ce; LGUID=20170328171202-9af4825b-1396-11e7-a59b-525400f775ce; showExpriedIndex=1; showExpriedCompanyHome=1; showExpriedMyPublish=1; hasDeliver=0; index_location_city=%E5%85%A8%E5%9B%BD; JSESSIONID=9E6568091D64AB8515B8E70D354BC10D; Hm_lvt_4233e74dff0ae5bd0a3d81c6ccf756e6=1490692322,1490704679,1490704945,1490746875; Hm_lpvt_4233e74dff0ae5bd0a3d81c6ccf756e6=1490748769; _ga=GA1.2.407060577.1490692322; LGSID=20170329082118-a0c3b596-1415-11e7-a659-525400f775ce; LGRID=20170329085249-080c8c0b-141a-11e7-9574-5254005c3644; SEARCH_ID=9bc41c0071964f8c804e9f67a0a5c073'}
html=requests.get(url,headers=headers)
data=json.loads(html.text)
return data
#獲取職位信息并存入列表
def getPosition(self,url):
data=self.getData(url)
position=data['content']['positionResult']['result']
po_list=[]
if position is not None:
for i in position:
main=[]
main.append(i['companyFullName'])
main.append(i['financeStage'])
main.append(i['positionName'])
main.append(i['positionLables'])
main.append(i['salary'])
main.append(i['city'])
main.append(i['education'])
main.append(i['workYear'])
main.append(i['jobNature'])
main.append(i['createTime'])
po_list.append(main)
return po_list
#獲取數(shù)據(jù),存入一個(gè)大的list
def saveDetail(self):
self.New=int(raw_input(u'請(qǐng)輸入要爬取的頁數(shù):'))
self.time=time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
print u'\n本地時(shí)間:',self.time
print u'\n開始采集數(shù)據(jù)...'
container=[]
for page in range(1,self.New+1):
self.url='https://www.lagou.com/jobs/positionAjax.json?px=new&first=true&pn='+str(page)+'&kd='+str(self.keyword)
po_list=self.getPosition(self.url)
time.sleep(3)
print u'第',page,u'項(xiàng)完畢'
container=container+po_list
return container
#將數(shù)據(jù)存入excel
def saveAll(self):
book=xlwt.Workbook()
sheet =book.add_sheet(str(self.keyword), cell_overwrite_ok=True)
container=self.saveDetail()
print u'\n采集完畢'
print u'\n準(zhǔn)備將數(shù)據(jù)存入表格...'
heads=[u'公司全名', u'融資狀況', u'工作名稱', u'標(biāo)簽', u'薪酬', u'城市', u'學(xué)歷要求',u'經(jīng)驗(yàn)要求',u'工作類型',u'數(shù)據(jù)創(chuàng)建時(shí)間']
ii=0
for head in heads:
sheet.write(0,ii,head)
ii+=1
i=1
for list in container:
j=0
for one in list:
sheet.write(i, j, one)
j+=1
i+=1
book.save(str(self.keyword)+'.xls')
print u'\n錄入成功!'
spider=Spider()
spider.saveAll()
有盆友可能會(huì)問了:隨便設(shè)個(gè)New簡(jiǎn)單,
可怎么獲得最大頁數(shù)呀?
好吧,我坦白:手動(dòng)試出來的
(先大概定個(gè)范圍,每次取中間數(shù),試個(gè)5、6次就出來了,也簡(jiǎn)單)
其實(shí)我也想過用個(gè)if position==[]或者if position=None就break結(jié)束循環(huán),可卻不知道為什么行不通,真是怪了??墒侨绻缺闅v獲取最大頁數(shù),后面又得遍歷一次,抓取次數(shù)多了,難保不被網(wǎng)站發(fā)現(xiàn)被封IP。
只好這樣了(這里有待改進(jìn))。
可以看到,整個(gè)爬取過程僅用request、json、xlwt等幾個(gè)關(guān)鍵庫。
總結(jié)爬蟲新思路:
直接用pn構(gòu)造URL實(shí)現(xiàn)翻頁,加上cookies偽裝成瀏覽器,get方式獲取####
是不是hin簡(jiǎn)單_
</br>
</br>
三、突破IP限制
爬蟲爬到一半時(shí),又出了幺蛾子

再上去一看

原來IP被封 了,難怪。
(這樣的情況還是第一次)
查了一下,網(wǎng)上有說可以用代理池。
可又得設(shè)計(jì)爬蟲抓代理,不免麻煩。
后面想到之前爬圖片網(wǎng)站時(shí),注冊(cè)的vpn。
vpn不就是代理么,還可各種線路隨便切換,哈哈哈我簡(jiǎn)直聰明~ (_)!
查了一點(diǎn)資料,有關(guān)反反爬及突破IP限制,
總結(jié)幾個(gè)方法:
1、設(shè)置代理池(可以網(wǎng)上抓代理,不過穩(wěn)定性是問題)
2、使用vpn(原理同上)
3、分布式抓?。ㄟ@個(gè)我也沒學(xué)到>_<)
4、設(shè)置等待時(shí)間,放慢抓取速度
5、修改請(qǐng)求頭( user_agent、cookies)
6、模擬登錄
當(dāng)然,最有效當(dāng)屬123
</br>
四、數(shù)據(jù)分析 — 一些感悟
工具用的BDP(奇妙的分析軟件)。
詞云用的標(biāo)簽一欄,直接丟BDP自動(dòng)生成。
后面發(fā)現(xiàn)有欠妥當(dāng),因?yàn)橛行?shù)據(jù)標(biāo)簽?zāi)且粔K什么都沒有。對(duì)幾個(gè)維度進(jìn)行了粗略分析,效果還不錯(cuò),比如這樣

細(xì)心的盆友可能又發(fā)現(xiàn)了,怎么沒有C# ?
其實(shí),我也想的。。。

如圖所示搜C#時(shí),會(huì)搜出許多C\C++的內(nèi)容,亂而麻煩,只好舍棄。
第一次親自參與3萬多數(shù)據(jù)的分析,新鮮。后面一想,其實(shí)爬蟲程序不過只是個(gè)采集數(shù)據(jù)的手段(或者說工具)。
關(guān)鍵還是具體的數(shù)據(jù)分析以及應(yīng)用轉(zhuǎn)化 單單抓個(gè)幾十萬爛在excel表里,沒有任何意義。
</br>
</br>
五、源碼剖析 — 新發(fā)現(xiàn)
爬過拉鉤的朋友肯定會(huì)發(fā)現(xiàn)一個(gè)現(xiàn)象:
打開一個(gè)頁面,過一陣子再重新打開
發(fā)現(xiàn)不再是原來頁面了,變成了別的。
可是真的是這樣么?
放幾個(gè)圖



get到了么?
只是順序變了下,內(nèi)容是不變的。
換湯不換藥,特么全是 障眼法 ?。。。?br> 難為了拉鉤的前端工程師 [攤手]
看來也只有我這種** 既無聊又聰明又有耐心**的人才會(huì)發(fā)現(xiàn)了

</br>
這個(gè)小項(xiàng)目我也放到了github上了:https://github.com/LUCY78765580/Python-web-scraping/blob/master/LaGou/LaGou.py
最后總結(jié)本篇 幾個(gè)要點(diǎn):
1、拉鉤爬蟲一般方法:Post模擬瀏覽器
2、新思路:get方式+cookies偽裝,
直接pn構(gòu)建URL實(shí)現(xiàn)翻頁和遍歷
3、突破IP限制(各種方法)
4、程序不過工具,關(guān)鍵策略、數(shù)據(jù)分析
5、源碼剖析新發(fā)現(xiàn):頁面原來障眼法
為了對(duì)得起這個(gè)"深入剖析"的標(biāo)題,小白已經(jīng)盡她最大的努力啦~
(學(xué)習(xí)爬蟲才一月左右,文章可能有不足之處,個(gè)中出入還請(qǐng)各位大神多多指正)
本篇就是這樣啦~