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

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

主要參考資料有:json

  1. B站視頻av44518113瀏覽器

  2. Python官方文檔安全

PS:若是筆記中有任何錯誤,歡迎在評論中指出,我會及時回覆並修改,謝謝服務器

問題描述

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

可是,我注意到了一個很是重要的細節,就是爬取不下來數據的緣由。拉勾網的Cookie中使用了時間戳,簡單的說,就是拉鉤網的cookie中有一個cookie是專門設置時間值的編輯器

正常瀏覽器訪問頁面的時候,瀏覽器首先獲取到了python職位頁面對應的HTML文本,再根據HTML文本中的連接請求相應的各類其餘數據,而後經過JS代碼將其復原爲完整頁面。正常請求過程當中,這個速度是很是快速的,時間值並不會過時。也就是說,時間值的設置對於拉勾網的正常訪問不會有任何影響。ide

但若是按照老師的視頻中所說的,咱們直接去爬取保存着職位信息的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'))

爬取成功後的結果:

爬取成功

相關文章
相關標籤/搜索