先说结论:最后失败告终,另辟蹊径,瞄准wap端。
用pyspider爬一个站,此站用了百度云加速的防护模块。防护原理就是通过js计算一个值,然后提交得到cookie,所以爬虫要支持js执行,来获取cookie。酌使用pyspider+phantomjs+代理 配置过程:链接后补。
先说一下为啥失败了:防护模块不但有js运行防护,还有ip限制,所以必须要挂代理,而pyspider的代理方案是用squid架设的动态热代理(squid代理的配置过程)。这种代理每次访问页面都随机获取一个代理池的ip。而百度云加速的防护的cookie是通过ip计算的,所以一旦换了ip,cookie也就失效了。(这句过后我在好好验证一下),所以必须保持抓取页面用的是同一个代理ip。虽然在pyspider的任务代码中,可以用save传递一个固定的代理ip。但是phantomjs的代理ip是在启动phantomjs进程的时候设定的动态代理。所以是没办法指定的,故而失败。
是否必须要固定ip的结论,我一会再试试。
过程代码:
这是百度验证的页面关键代码:
麻蛋,不知道为啥简书突然粘贴不了复制的代码,只好上图。
↑这张图是通过js计算,得到一个jschl-answer 参数(是一个或正或负的数字)。 ↑然后在这里提交给地址:/cdn-cgi/l/chk_jshl所以我们这样计算jschl-answer 参数:
self.crawl(url, callback=self.check_page, fetch_type='js', js_script=r'''
function() {
var script = document.querySelector('script').textContent;
console.log(script);
script = script.match(new RegExp("setTimeout\\(function\\(\\){([\\s\\S\n]+)f.submit", 'm'))[1] + 'a.value;';
console.log(script);
return eval(script);
}
''',save=data)
此代码来源于V2EX ,是pyspider作者@binux的回答,地址:https://www.v2ex.com/t/311014
大意就是在url页,运行js,把运行的结果传递给下一页(check_page)
check_page的代码:
self.crawl(url+'/cdn-cgi/l/chk_jschl', callback=self.chk_jschl, params={
'jschl_vc': response.doc('input[name=jschl_vc]').val(),
'pass': response.doc('input[name=pass]').val(),
'jschl-answer': response.js_script_result
}, cookies=response.cookies)
大意是:通过上一页传递来的js计算结果,也就是jschl-answer,提交到url+'/cdn-cgi/l/chk_jschl'页面,获取cookie
至此,到下一页的时候,正确的cookie就算获取完成了,接下来用获取的cookie就可以正常爬取页面了。
网友评论