requests 返回 521
记录下,免得忘,菜鸟一只,有问题请指出
目录
req = requests.get(surl, headers=header, timeout=10)
打印req.status_code是521, 查了下,是js加密cookie的手,即第一次访问 返回521 给浏览器设置cookies 二次刷新,你的浏览器就可以用设置上的cookie自动访问了
方法一 :要是你只爬取一次,可以手动获取cookie
header = b'''
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.9
Cookie: maxPageNum4939820=11; __jsluid=8fa6cf21ff713384ac4ec74e5b42606a; zh_choose=n; __jsl_clearance=1551101660.999|0|P83Ao8EIBvxZjzXw760v6cWCSa0%3D
Host: www.mps.gov.cn
User-Agent: Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Mobile Safari/537.36'''
req = requests.get(surl, headers=headers_raw_to_dict(header))
if 200 == req.status_code:
req.encoding = 'utf-8'
return req.text
方法二 使用exejs执行js代码返回cookie
引用 https://blog.****.net/qq_27302597/article/details/79411808
对此 我们的做法是让Python运行js代码,获取cookies 并且加到下次访问的头部
我们首先获取返回的源代码
def get_521_content():
headers = {
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.119 Safari/537.36'
}
req = requests.get('https://www.seebug.org/vuldb/ssvid-92666', headers=headers)
cookies = req.cookies
cookies = '; '.join(['='.join(item) for item in cookies.items()])
txt_521 = req.text
txt_521 = ''.join(re.findall('<script>(.*?)</script>', txt_521))
return (txt_521, cookies)
我们需要返回的分别是两个 第一个是网页的源代码 第二个是后台设置的cookie,然后我们对拿来的js代码进行修改并且运行,我使用的Python 执行js的模块是execjs ,主要的修改是将eval 替换成return 让他有返回值给咱看到
def fixed_fun(function):
func_return=function.replace('eval','return')
content=execjs.compile(func_return)
evaled_func=content.call('f')
我们可以看到代码解密出来有变成了新的一串js代码
我们可以把他放到html文件里面运行
我这里是直接放到exejs中运行的,对代码也进行了各种修改,最重要的是将document.cookie=()函数替换成return这样就可以直接用print输出返回的内容了,对于其他的修改,大家只要那里报错删那里就行。
mode_func=evaled_func.replace('while(window._phantom||window.__phantomas){};','').\
replace('document.cookie=','return').replace(';if((function(){try{return !!window.addEventListener;}','').\
replace("catch(e){return false;}})()){document.addEventListener('DOMContentLoaded',l,false);}",'').\
replace("else{document.attachEvent('onreadystatechange',l);}",'').replace(r"setTimeout('location.href=location.href.replace(/[\?|&]captcha-challenge/,\'\')',1500);",'')
content = execjs.compile(mode_func)
cookies=content.call('l')
__jsl_clearance=cookies.split(';')[0]
return __jsl_clearance
经过了一堆修改之后,
if __name__ == '__main__':
func=get_521_content()
content=func[0]
cookie_id=func[1]
print(cookie_id)
cookie_js=fixed_fun(func[0])
print(cookie_js)
__jsl_clearance=1519886795.502|0|fysySG50HEux2yfs1Te%2FEOSEAyk%3D
我们会惊奇的发现,Python执行了js代码,并且返回了一段cookie,他就是我们想要的!之后我们需要做的事就比较轻松了,只需要把后台设置的__jsluid 和js设置的cookie __jsl_clearance一起加入我们的浏览器头就可以正常访问了,需要注意的是 User-Agent 一定要和第一次访问设置的一模一样,不然照样返回521
可以放肆的爬取了,如果遇到521,就调用第一个访问的函数,运行js换新的cookie就行!
但是在exejs那卡死了,遂换另一种方式,有时间再研究这种方式
方法三 selenium
def driver_chrome():
chrome_options = Options()
chrome_options.add_argument("--headless")
chrome_options.add_argument('--no-sandbox')
chrome_options.add_argument("--disable-gpu")
chrome_options.add_argument("--window-size=1920x1080")
driver = webdriver.Chrome(chrome_options=chrome_options)
return driver
def get_cookies(self, surl):
session = {}
driver = sc_fun.driver_chrome()
driver.get(surl)
cookies = driver.get_cookies()
for i in cookies:
session[i.get('name')] = i.get('value')
driver.close()
driver.quit()
return session
打印出来可以看到
{'__jsluid': 'ade4da62cd6fdc4df557c1344897e46d', '__jsl_clearance': '1551162902.894|0|qMRnlDFAz6ZJNA%2BPunAHqQ7RWj4%3D'}
封装到 cookies中请求就好了