在CSDN首頁上看到的拉勾職位資訊爬取。
ps:自學新人
時間 2020年6月6日
思路:
廢話不多說
我的目的和看到的别人的不太一樣,是通過自己輸入一個不确定的職位資訊,爬取到職位的詳情,比如崗位職責,要求之類的。
說幹就幹,碰到問題再想辦法解決。
打開首頁(https://www.lagou.com)随意搜尋一個職位,以python為例,在跳轉到的有關職位清單頁檢視詳情頁,恩,果然沒有需要的資料,就去控制台抓包,篩選出XHR,如圖
可以看到這個包内貌似是有需要的東西的,那就繼續,點一個具體的職位,進入詳情頁,再看網頁源碼,
有需要的東西,網頁通路到這裡就可以,再看位址欄,有一個參數show,
先試試最簡單的辦法,把它删了,再次通路發現沒有問題,好,不管她了,就剩下一個問題,網址裡的數字6991626是哪來的,既然是二級頁面網址的一部分,那就要去一級頁面上去找,把它複制,在控制台搜一下
發現在一級頁面json資料下
到目前為止,初步的路線已經有了,通路首頁,從其json資料中擷取具體職位的id碼,拼接成一個新的url在對其通路,就可以得到有職位具體資訊的源碼了
從首頁json資料包的Headers下,可以看到它實際發起請求的url是https://www.lagou.com/jobs/positionAjax.json?needAddtionalResult=false
請求類型是post,那就勢必和form表單有關了,下邊果然有,參數都很簡單,沒有加密的,這就很友好,多點選幾個職可以發現第一個參數first固定為true,第二個就是頁碼數了,最後一個是搜尋的關鍵字
貌似很簡單,試一下
具體子產品的導入就不多說了
url = 'https://www.lagou.com/jobs/positionAjax.json?needAddtionalResult=false'
data = {
'first': 'true',
'pn': 1,
'kd': 'python'
}
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 '
'(KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36'}
res = requests.post(url, data=data,headers=headers).json()
print(res)
然後,報錯
{‘status’: False, ‘msg’: ‘您操作太頻繁,請稍後再通路’, ‘clientIp’: ‘221.192.180.249’, ‘state’: 2402}
又試了往headers裡加上剩下的東西,還是報錯,猜測是和cookies有關,因為觀察過,即使搜尋同一個職位,每次的cookies也不一樣,就去查資料看到有個人爬取的是python有關職位的資訊,是通過向網頁https://www.lagou.com/jobs/list_python發送一個帶查詢關鍵字python的get請求,擷取其中的cookies之後,再用在擷取json資料的網頁請求中,就試了一下,成了
代碼比較亂,勿噴勿噴
import requests
import json
from fake_useragent import FakeUserAgent
user_li = FakeUserAgent()
# 輸入查詢崗位,獲得cookies
class LgCookies(object):
def __init__(self, keyword):
# 擷取cookies的url和查詢關鍵字拼接
self.url = 'https://www.lagou.com/jobs/list_{}'.format(keyword)
# get請求的反爬貌似基本沒有,是以請求頭很簡單,隻是僞裝一下浏覽器
self.cookies_headers = {'User-Agent': user_li.random}
def get_kd_cookies(self):
cookies = requests.get(self.url, headers=self.cookies_headers).cookies
return cookies
# 爬取查詢職位的網頁源碼
class LgSpider(object):
def __init__(self, cookies, keyword):
# 需要查詢職位的實際請求位址
self.url = 'https://www.lagou.com/jobs/positionAjax.json?needAddtionalResult=false'
# form 表單,這裡隻簡單設定一頁,如果想請求多的,設定一個循環加一個判斷傳回的json資料中需要的資料是否為空應該就可以
self.data = {'first': 'true',
'pn': 1,
'kd': keyword
}
# 僞裝請求發起人
self.headers = {'User-Agent': user_li.random,
'origin': 'https://www.lagou.com',
'referer': 'https://www.lagou.com/jobs/list_{}'.format(keyword)
}
self.cookies = cookies
def do_request(self, url=None, data=None, headers=None, cookies=None):
res = requests.post(url=url, data=data, headers=headers, cookies=cookies)
return res
def get_jobID(self):
positionID_li = []
data = self.do_request(url=self.url, data=self.data, headers=self.headers,cookies=self.cookies)
res = data.json()
for position in res['content']['positionResult']['result']:
positionID_li.append(position['positionId'])
return positionID_li
def get_job_info(self):
p_id = self.get_jobID()
for id in p_id:
url = 'https://www.lagou.com/jobs/{}.html'.format(id)
res = requests.get(url=url, headers=self.headers).text
print(res)
if __name__ == '__main__':
key_word=input('請輸入搜尋職位:')
want_job = LgCookies(key_word)
# want_job.get_kd_cookies()
cookies = want_job.get_kd_cookies()
get_info = LgSpider(cookies, key_word)
get_info.get_job_info()
剩下的提取崗位詳細資訊的具體内容,沒有再去寫,就是提取資料的問題了,應該不難,用xpath吧,懶得試了。。。。
結束!!