關於千里馬招標網知道創宇反爬蟲521狀態碼的解決方案(python代碼模擬js生成cookie _clearence值)

1、問題發現

近期我在作代理池的時候,發現了一種之前沒有見過的反爬蟲機制。當我用常規的requests.get(url)方法對目標網頁進行爬取時,其返回的狀態碼(status_code)爲521,這是一種之前沒有見過的狀態碼。再輸出它的爬取內容(text),發現是一些js代碼。看來是新問題,咱們來探索一下。html

 
狀態碼和爬取內容.png

2、原理分析

打開Fiddler,抓取訪問網站的包,咱們發現瀏覽器對於同一網頁連續訪問了兩次,第一次的訪問狀態碼爲521,第二次爲200(正常訪問)。看來網頁加了反爬蟲機制,須要兩次訪問纔可返回正常網頁。python

 
Fiddler抓包信息.png

下面咱們來對比兩次請求的區別:正則表達式

521請求:瀏覽器

 
521請求.png

200請求:bash

 
200請求.png

經過對比兩次請求頭,咱們發現第二次訪問帶了新的cookie值。再考慮上面程序對爬取結果的輸出爲js代碼,能夠考慮其操做過程爲:第一次訪問時服務器返回一段可動態生成cookie值的js代碼;瀏覽器運行js代碼生成cookie值,並帶cookie從新進行訪問;服務器被正常訪問,返回頁面信息,瀏覽器渲染加載。服務器

3、解決流程

弄清楚瀏覽器的執行過程後,咱們就能夠模擬其行爲經過python做網頁爬取。操做步驟以下:cookie

  1. 用request.get(url)獲取js代碼函數

  2. 經過正則表達式對代碼進行解析,得到JS函數名,JS函數參數和JS函數主體,並將執行函數eval()語句修改成return語句返回cookie值網站

  3. 調用execjs庫的executeJS()功能執行js代碼得到cookie值url

  4. 將cookie值轉化爲字典格式,用request.get(url, cookies = cookie)方法獲取獲得正確的網頁信息

4、代碼實現

實現程序所須要用到的庫:

import re #實現正則表達式 import execjs #執行js代碼 import requests #爬取網頁 

第一次爬取得到包含js函數的頁面信息後,經過正則表達式對代碼進行解析,得到JS函數名,JS函數參數和JS函數主體,並將執行函數eval()語句修改成return語句返回cookie值。

# js_html爲得到的包含js函數的頁面信息 # 提取js函數名 js_func_name = ''.join(re.findall(r'setTimeout\(\"(\D+)\(\d+\)\"', js_html)) ​ # 提取js函數參數 js_func_param = ''.join(re.findall(r'setTimeout\(\"\D+\((\d+)\)\"', js_html)) ​ # 提取js函數主體 js_func = ''.join(re.findall(r'(function .*?)</script>', js_html)) 

將執行函數eval()語句修改成return語句返回cookie值

# 修改js函數,返回cookie值 js_func = js_func.replace('eval("qo=eval;qo(po);")', 'return po') 

調用execjs庫的executeJS()功能執行js代碼得到cookie值

# 執行js代碼的函數,參數爲js函數主體,js函數名和js函數參數 def executeJS(js_func, js_func_name, js_func_param): jscontext = execjs.compile(js_func) # 調用execjs.compile()加載js函數主體內容 func = jscontext.call(js_func_name,js_func_param) # 使用call()經過函數名和參數執行該函數 return func cookie_str = executeJS(js_func, js_func_name, js_func_param) 

將cookie值轉化爲字典格式

# 將cookie值解析爲字典格式,方便後面調用 def parseCookie(string): string = string.replace("document.cookie='", "") clearance = string.split(';')[0] return {clearance.split('=')[0]: clearance.split('=')[1]} cookie = parseCookie(cookie_str) 

得到cookie後,採用帶cookie的方式從新進行爬取,便可得到咱們須要的網頁信息了。

做者:欲摘桃花換酒錢連接:https://www.jianshu.com/p/37d549a4bf44來源:簡書

相關文章
相關標籤/搜索