快捷搜索:  汽车  科技

java 爬虫读取cookie(Python爬虫破解JS加密的Cookie)

java 爬虫读取cookie(Python爬虫破解JS加密的Cookie)打开Fiddler软件,用浏览器打开目标站点(http://www.kuaidaili.com/proxylist/2/) 。可以发现浏览器对这个页面加载了两次,第一次返回521,第二次才正常返回数据。很多没有写过网站或是爬虫经验不足的童鞋,可能就会觉得奇怪为什么会这样?为什么浏览器可能正常返回数据而代码却不行?发现问题前言在GitHub上维护了一个代理池的项目,代理来源是抓取一些免费的代理发布网站。上午有个小哥告诉我说有个代理抓取接口不能用了,返回状态521。抱着帮人解决问题的心态去跑了一遍代码。发现果真是这样。通过Fiddler抓包比较,基本可以确定是JavaScript生成加密Cookie导致原来的请求返回521。

来源:Python中文社区 作者:Jerry

  • Jerry,Python中文社区专栏作者。

  • blog:https://my.oschina.net/jhao104/blog

  • github:https://github.com/jhao104

前言

在GitHub上维护了一个代理池的项目,代理来源是抓取一些免费的代理发布网站。上午有个小哥告诉我说有个代理抓取接口不能用了,返回状态521。抱着帮人解决问题的心态去跑了一遍代码。发现果真是这样。

通过Fiddler抓包比较,基本可以确定是JavaScript生成加密Cookie导致原来的请求返回521。

发现问题

打开Fiddler软件,用浏览器打开目标站点(http://www.kuaidaili.com/proxylist/2/) 。可以发现浏览器对这个页面加载了两次,第一次返回521,第二次才正常返回数据。很多没有写过网站或是爬虫经验不足的童鞋,可能就会觉得奇怪为什么会这样?为什么浏览器可能正常返回数据而代码却不行?

java 爬虫读取cookie(Python爬虫破解JS加密的Cookie)(1)

仔细观察两次返回的结果可以发现:

java 爬虫读取cookie(Python爬虫破解JS加密的Cookie)(2)

1、第二次请求比第一次请求的Cookie内容多了个这个

_ydclearance=0c316df6ea04c5281b421aa8-5570-47ae-9768-2510d9fe9107-1490254971

2、第一次返回的内容一些复杂看不懂的JS代码,第二次返回的就是正确的内容。

其实这是网站反爬虫的常用手段。大致过程是这样的:首次请求数据时,服务端返回动态的混淆加密过的JS,而这段JS的作用是给Cookie添加新的内容用于服务端验证,此时返回的状态码是521。浏览器带上新的Cookie再次请求,服务端验证Cookie通过返回数据(这也是为嘛代码不能返回数据的原因)。

解决问题

其实我第一次遇到这样的问题是,一开始想的就是既然你是用JS生成的Cookie 那么我也可以将JS函数翻译成Python运行。但是最后还是发现我太傻太天真,因为现在的JS都流行混淆加密,原始的JS这样的:

java 爬虫读取cookie(Python爬虫破解JS加密的Cookie)(3)

java 爬虫读取cookie(Python爬虫破解JS加密的Cookie)(4)

看到这样的JS代码,我只能说原谅我JS能力差,还原不了。。。

但是前端经验丰富的童鞋马上就能想到还有种方法可解,那就是利用浏览器的JS代码调试功能。这样一切就迎刃而解,新建一个html文件,将第一次返回的html原文复制进去,保存用浏览器打开,在eval之前打上断点,看到这样的输出:

java 爬虫读取cookie(Python爬虫破解JS加密的Cookie)(5)

可以看到这个变量po为 document.cookie='_ydclearance=0c316df6ea04c5281b421aa8-5570-47ae-9768-2510d9fe9107-1490254971; expires=Thu 23-Mar-17 07:42:51 GMT; domain=.kuaidaili.com; path=/'; window.document.location=document.URL,下面还有个 eval("qo=eval;qo(po);")。

JS里面的eval和Python的差不多,第二句的意思就是将eval方法赋给qo。然后去eval字符串po。而字符串po的前半段的意思是给浏览器添加Cooklie 后半段window.document.location=document.URL是刷新当前页面。

这也印证了我上面的说法,首次请求没有Cookie,服务端回返回一段生成Cookie并自动刷新的JS代码。浏览器拿到代码能够成功执行,带着新的Cookie再次请求获取数据。而Python拿到这段代码就只能停留在第一步。

那么如何才能使Python也能执行这段JS呢,答案是PyV8。V8是Chromium中内嵌的javascript引擎,号称跑的最快。PyV8是用Python在V8的外部API包装了一个python壳,这样便可以使python可以直接与javascript操作。PyV8的安装大家可以自行百度。

代码

分析完成,下面切入正题撸代码。

首先是正常请求网页,返回带加密的JS函数的html:

java 爬虫读取cookie(Python爬虫破解JS加密的Cookie)(6)

java 爬虫读取cookie(Python爬虫破解JS加密的Cookie)(7)

请点击此处输入图片描述由于返回的是html,并不单纯的JS函数,所以需要用正则提取JS函数的参数的参数。

java 爬虫读取cookie(Python爬虫破解JS加密的Cookie)(8)

java 爬虫读取cookie(Python爬虫破解JS加密的Cookie)(9)

还有一点需要注意,在JS函数中并没有返回cookie,而是直接将cookie set到浏览器,所以我们需要将eval("qo=eval;qo(po);")替换成return po这样就能成功返回po中的内容。

java 爬虫读取cookie(Python爬虫破解JS加密的Cookie)(10)

这样返回的cookie是字符串格式,但是用requests.get()需要字典形式,所以将其转换成字典:

java 爬虫读取cookie(Python爬虫破解JS加密的Cookie)(11)

最后带上解析出来的Cookie再次访问网页,成功获取数据:

java 爬虫读取cookie(Python爬虫破解JS加密的Cookie)(12)

本文完整源码已上传至Python学园,欢迎进入下载并讨论本文内容。

猜您喜欢: