看了半天帖子都是都是通过selenium破解js加密的,个人感觉用selenium破解js加密效率太低,而且繁琐,根据目前业务需求就自己研究了一下同花顺的js加密。
通过接口测试工具直接请求接口发现获取不到该网站实际的页面数据;
如下图看到了页面有加载了一段js 与 window.location这个方法,可以大概猜出直接打开网站链接,再不带cookie的情况下每次请求都会通过js生成一段密钥,然后将密钥携带在某个参数中,然后通过window.location再重新访问一次该接口才会加载才会出现浏览器页面显示的数据。
清楚掉浏览器的cookie等缓存信息,直接打开请求接口,发现该网站发送了两次一样的请求,第一次没cookie也没有任何的返回数据;
第二次请求在中多了一个cookie,同时返回页面数据,说明与开始猜想不谋而合,第一次请求无cookie会生成一个cookie然后通过 window.location再调用这个接口展示真正的数据信息。
接下来多请求几次之后发现每次请求接口发现每一次请求cookie中的参数v都会发生变化。
了解了该网站的加密方式以后我们就需要重点分析第一次请求中这个cookie是如何生成的,下面就需要重点分析这段js:https://s.thsi.cn/js/chameleon/chameleon.min.1574850.js
打开之后看到密密麻麻一大堆看的,这时候无需全部看明白,只要找到js中是如何生成cookie参数的这一段js方法就好了。
将js格式化之后发现它是通过一堆参数调用最外层的这一个大方法
而且很多js的方法都是通过参数传递进去的,这下看起来还挺有趣。
下面就需要开始打断点看这段js究竟是如何生成cookie的;
修改js只需要将它update到cookie中的方法return一下,生成的cookie就可以捕获到了。
关于中间修改js的这一段过程长路漫漫需要自己去摸索,下面是我修改后的js代码 aes.min.js
我封装了一个函数v,调用这个函数v就可以直接返回动态生成的cookie中的参数v。
我们通过python代码运行这段js然后调用一下函数v
在这里我使用的是python 中的execjs模块来模拟运行js代码的,当然你也可以选择其他的。
改编后的js文件代码 直接运行即可。
链接:https://pan.baidu.com/s/1wqZOJGqBVD9cwdsrxX9Psg 密码:zk7d
每次请求之前调用一下就可以了
import execjs
with open('./aes.min.js', 'r') as f:
jscontent = f.read()
context= execjs.compile(jscontent)
print(context.call("v"))
下面我们生成一下cookie带入接口中来测试一下:
获取了前10页的内容信息
下面是代码
import execjs
import requests
from lxml import etree
import re
with open('./aes.min.js', 'r') as f:
jscontent = f.read()
context= execjs.compile(jscontent)
headers = {
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.119 Safari/537.36',
'cookie': ''
}
url = 'http://www.iwencai.com/search?w=火币&tid=news&st=1&p={}'
for i in range(1,11): # 请求10页
headers['cookie'] = 'v={}'.format(context.call("v"))
req = requests.get(url.format(i), headers=headers)
html = etree.HTML(req.text)
text = html.xpath("//div[@id='hidelist']//div[@class='s_r_box']")
print('page{},{},cookie{}'.format(i,"*"*10, headers['cookie']))
for t in text:
titles = t.xpath(".//h2[@class='s_r_blue_title']//text()")
title = ''
for tit in titles:
tit = re.sub(r'\n+|\t+|\r+|\s+', '', tit)
title = title + tit
print(title)
这样我们就可以直接获取到所需要的数据了,无需通过selenium来模拟浏览器操作行为,提升了抓取效率。
最后当然要记得,使用一些代理可以帮助我们更快捷的获取网站呢数据。