本筆記寫於2020年2月4日。Python版本爲3.7.4,編輯器是VS codepython
主要參考資料有:json
B站視頻av44518113瀏覽器
Python官方文檔安全
PS:若是筆記中有任何錯誤,歡迎在評論中指出,我會及時回覆並修改,謝謝服務器
看B站學習視頻的時候,老師講得第一個實戰也就是爬取拉勾網數據是怎麼也爬取不下來,彈幕裏的方法也都無論用。因此開始求助偉大的度娘,度娘中大部分的解決方法都是使用requests
庫來爬取的,但目前只學習的urllib
庫,因此沒辦法採用。cookie
可是,我注意到了一個很是重要的細節,就是爬取不下來數據的緣由。拉勾網的Cookie中使用了時間戳,簡單的說,就是拉鉤網的cookie中有一個cookie是專門設置時間值的。編輯器
正常瀏覽器訪問頁面的時候,瀏覽器首先獲取到了python職位頁面對應的HTML文本,再根據HTML文本中的連接請求相應的各類其餘數據,而後經過JS代碼將其復原爲完整頁面。正常請求過程當中,這個速度是很是快速的,時間值並不會過時。也就是說,時間值的設置對於拉勾網的正常訪問不會有任何影響。ide
但若是按照老師的視頻中所說的,咱們直接去爬取保存着職位信息的json
數據,就算是複製了全部的響應頭也沒有用,由於cookie中的時間值已通過期了。服務器接受到這種爬蟲請求後,就會返回您操做太頻繁,請稍後再訪問這句話了。學習
爬取拉勾網數據的關鍵就是快,只要時間戳沒有超期就能夠爬取成功。網站
咱們這裏分三個步驟:
json
數據這一步的目的只有一個,就是找到表明時間值的cookie。
首先經過程序,咱們來看一下返回回來的響應頭都有什麼?
from urllib import request import ssl # 去掉全局安全校驗 ssl._create_default_https_context = ssl._create_unverified_context url = 'https://www.lagou.com/jobs/list_python?labelWords=&fromSearch=true&suginput=' req = request.Request(url, headers={ 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36' }) # 開始請求 response = request.urlopen(req) for header in response.getheaders(): print(header)
結果以下:
能夠看到共有4個Set-Cookie
的響應頭,其中我以爲可能表示時間值的響應頭是user_trace_token
,由於我從裏面看到了時間信息20200204184124
這個時間戳(但我也不肯定)。
既然找到了響應頭,咱們接下來就要提取cookie,並構造接下來請求頭的cookie。
cookie = '' for header in response.getheaders(): if header[0] == 'Set-Cookie': print(header[1].split(';')[0]) cookie = cookie + header[1].split(';')[0] + '; ' cookie = cookie[:-1] print(cookie)
結果以下:
接下來和老師的代碼就沒什麼區別了,就是要在咱們構造的請求頭裏加上咱們剛纔提取的cookie
# -*- coding: utf-8 -*- from urllib import request from urllib import parse import ssl # 去掉全局安全校驗 ssl._create_default_https_context = ssl._create_unverified_context # 先爬取首頁python職位的網站以獲取Cookie url = 'https://www.lagou.com/jobs/list_python?labelWords=&fromSearch=true&suginput=' req = request.Request(url, headers={ 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36' }) response = request.urlopen(req) # 從響應頭中提取Cookie cookie = '' for header in response.getheaders(): if header[0] == 'Set-Cookie': cookie = cookie + header[1].split(';')[0] + '; ' # 去掉最後的空格 cookie = cookie[:-1] # 爬取職位數據 url = 'https://www.lagou.com/jobs/positionAjax.json?city=%E5%8C%97%E4%BA%AC&needAddtionalResult=false' # 構造請求頭,將上面提取到的Cookie添加進去 headers = { 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36', 'Cookie': cookie, 'Referer': 'https://www.lagou.com/jobs/list_python?labelWords=&fromSearch=true&suginput=' } data = { 'first': 'true', 'pn': 1, 'kd': 'python' } req = request.Request(url, data=parse.urlencode(data).encode('utf-8'), headers=headers) response = request.urlopen(req) print(response.read().decode('utf-8'))
爬取成功後的結果: