拉勾網的反爬介紹和解決方法(更新時間:2019/2/19)

拉勾網的反爬介紹和解決方法(更新時間:2019/2/19)

1. 前言

最近拉勾的反爬改動比較頻繁,公司採集拉勾網的爬蟲又無法正式運行,花了近一週的時間來處理拉勾網的反爬問題,特別寫一篇博客來記錄一下拉勾的反爬

2. 簡述

爬拉勾的時候,主要是採集職位相關的信息,涉及到頁面有3個:

  1. 輸入關鍵詞搜索後得到的職位列表頁:https://www.lagou.com/jobs/list_python?px=new&city=%E4%B8%8A%E6%B5%B7#order
  2. 職位詳情頁:https://www.lagou.com/jobs/5371803.html
  3. 公司詳情頁:https://www.lagou.com/gongsi/225514.html

3. 反爬介紹

3.1、對於職位的詳情頁和公司的詳情頁的反爬:

職位的詳情頁公司的詳情頁的信息都能在頁面源代碼中獲取到,請求這兩個頁面也沒有使用太多反爬,只需要在請求的時候加入headers參數即可,不過前提是你知道頁面的URL,即你需要在職位列表頁中獲取到職位id和公司id,才能拼接URL,得到相關的職位詳情頁和公司詳情頁

3.2、對於職位列表頁的反爬:

要獲取職位列表的信息,相對於比職位和公司的詳情頁,難度的要大一點


列表頁使用了ajax加載,直接去請求原網頁是獲取不到想要的信息,我們打開網頁:https://www.lagou.com/jobs/list_java?labelWords=&fromSearch=true&suginput=?labelWords=hot,看一下源代碼

image

源代碼沒有我們需要的數據,但是網頁上有顯示數據,那麼數據肯定是以別的方式傳過來的,我們找一下數據,看哪個請求中有返回有我們需要的數據,看下找到的請求,按一下F12進入開發者模式,再點擊Network-->XHR-->點擊第一個請求-->response

image

這裏返回的是一個json的可是,裏面有我們需要的信息(按ctrl+F搜索關鍵字驗證信息是否在返回的數據中)

既然找到我們需要的數據,那麼如何讓爬蟲來獲取到呢,點擊Headers,我們看一下請求頭,發現是個post請求,直接去構造請求來訪問這個接口,發現返回的是

{"status":false,"msg":"您操作太頻繁,請稍後再訪問","clientIp":"183.160.238.206","state":2402}

並不是你訪問頻繁,是因爲網站對cookies設置了反爬,cookies每次訪問都會發生變化,想要獲取這個接口的數據,需要請求2次,第一次請求的頁面是源代碼那個頁面(即:https://www.lagou.com/jobs/list_java?labelWords=&fromSearch=true&suginput=?labelWords=hot),直接get請求這個頁面,雖然不能直接獲取到需要的數據,但是能獲取到cookies,服務器返回的時候會返回一個cookies參數,來更新cookies,我們在把更新後的cookies,放到post請求的參數中,就可以獲取到接口的數據了

image

我們看一下成功請求的代碼:

import requests
'''
說明:本代碼只是測試,你能夠使用它獲得一次請求的數據,需要連續請求還請修改代碼

'''
headers = {
    'Connection': 'keep-alive',
    'Cache-Control': 'max-age=0',
    'Upgrade-Insecure-Requests': '1',
    'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.80 Safari/537.36',
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
    'Accept-Encoding': 'gzip, deflate, br',
    'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8',
}
response = requests.get(
    'https://www.lagou.com/jobs/list_?city=%E4%B8%8A%E6%B5%B7&cl=false&fromSearch=true&labelWords=&suginput=',
    headers=headers)  # 請求原網頁
r = requests.utils.dict_from_cookiejar(response.cookies)  # 獲取cookies
r["user_trace_token"] = r["LGRID"]
r["LGSID"] = r["LGRID"]
r["LGUID"] = r["LGRID"]  # 構造cookies的參數
cookies = {
    'X_MIDDLE_TOKEN': '797bc148d133274a162ba797a6875817',
    'JSESSIONID': 'ABAAABAAAIAACBI03F33A375F98E05C5108D4D742A34114',
    '_ga': 'GA1.2.1912257997.1548059451',
    '_gat': '1',
    'Hm_lvt_4233e74dff0ae5bd0a3d81c6ccf756e6': '1548059451',
    'user_trace_token': '20190121163050-dbd72da2-1d56-11e9-8927-525400f775ce',
    'LGSID': '20190121163050-dbd72f67-1d56-11e9-8927-525400f775ce',
    'PRE_UTM': '',
    'PRE_HOST': '',
    'PRE_SITE': '',
    'PRE_LAND': 'https%3A%2F%2Fwww.lagou.com%2F%3F_from_mid%3D1',
    'LGUID': '20190121163050-dbd73128-1d56-11e9-8927-525400f775ce',
    '_gid': 'GA1.2.1194828713.1548059451',
    'index_location_city': '%E5%85%A8%E5%9B%BD',
    'TG-TRACK-CODE': 'index_hotjob',
    'LGRID': '20190121163142-fb0cc9c0-1d56-11e9-8928-525400f775ce',
    'Hm_lpvt_4233e74dff0ae5bd0a3d81c6ccf756e6': '1548059503',
    'SEARCH_ID': '86ed37f5d8da417dafb53aa25cd6fbc0',
}
cookies.update(r)  # 更新接口的cookies
headers = {
    'Origin': 'https://www.lagou.com',
    'X-Anit-Forge-Code': '0',
    'Accept-Encoding': 'gzip, deflate, br',
    'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8',
    'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.80 Safari/537.36',
    'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
    'Accept': 'application/json, text/javascript, */*; q=0.01',
    'Referer': 'https://www.lagou.com/jobs/list_java?px=new&city=%E4%B8%8A%E6%B5%B7',
    'X-Requested-With': 'XMLHttpRequest',
    'Connection': 'keep-alive',
    'X-Anit-Forge-Token': 'None',
}

params = (
    ('px', 'new'),
    ('city', '\u4E0A\u6D77'),
    ('needAddtionalResult', 'false'),
)

data = {'first': True,
        'kd': 'java',
        'pn': 1}
response = requests.post('https://www.lagou.com/jobs/positionAjax.json', headers=headers, params=params,
                         cookies=cookies, data=data)  # 請求接口
print(response.json())

3.3、注意:

  1. 這樣可以單次請求接口獲取到數據,每次請求接口之前都要請求原網頁,以獲取cookies
  2. 每次請求列表頁數據接口的時間間隔保持在1秒以上,不然可能會被封ip
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章