Python爬蟲實戰(一) 使用urllib庫爬取拉勾網數據


本筆記寫於2020年2月4日。Python版本為3.7.4,編輯器是VS code

主要參考資料有:

  1. B站視頻av44518113

  2. Python官方文檔

PS:如果筆記中有任何錯誤,歡迎在評論中指出,我會及時回復並修改,謝謝

問題描述

看B站學習視頻的時候,老師講得第一個實戰也就是爬取拉勾網數據是怎么也爬取不下來,彈幕里的方法也都不管用。所以開始求助偉大的度娘,度娘中大部分的解決方法都是使用requests庫來爬取的,但目前只學習的urllib庫,所以沒辦法采用。

但是,我注意到了一個非常重要的細節,就是爬取不下來數據的原因。拉勾網的Cookie中使用了時間戳,簡單的說,就是拉鈎網的cookie中有一個cookie是專門設置時間值的

正常瀏覽器訪問頁面的時候,瀏覽器首先獲取到了python職位頁面對應的HTML文本,再根據HTML文本中的鏈接請求相應的各種其他數據,然后通過JS代碼將其復原為完整頁面。正常請求過程中,這個速度是非常快速的,時間值並不會過期。也就是說,時間值的設置對於拉勾網的正常訪問不會有任何影響。

但如果按照老師的視頻中所說的,我們直接去爬取保存着職位信息的json數據,就算是復制了所有的響應頭也沒有用,因為cookie中的時間值已經過期了。服務器接受到這種爬蟲請求后,就會返回您操作太頻繁,請稍后再訪問這句話了。

解決辦法

爬取拉勾網數據的關鍵就是快,只要時間戳沒有超期就可以爬取成功。

我們這里分三個步驟:

  1. 爬取拉勾網的Python職位頁面
  2. 提取上面爬取到頁面的時間戳cookie
  3. 將時間戳cookie添加到請求頭中,再請求保存着職位的json數據

獲取python職位頁面

這一步的目的只有一個,就是找到代表時間值的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。

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

接下來和老師的代碼就沒什么區別了,就是要在我們構造的請求頭里加上我們剛才提取的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'))

爬取成功后的結果:

爬取成功


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM