本文爬取的网站如下(可以找解密工具解码)
aHR0cHM6Ly9uZXdyYW5rLmNuLw==
爬取的内容为网站的资讯情报版块的新闻资讯
鼠标点击翻页,在开发者工具中查看请求包,很容看出请求地址和参数,
其中变化的参数为nonce和xyz,我们的目标就是找出这两个参数的加密原理,就是加密函数。然后用python代码编写函数生成该加密参数,或者抠出JS代码,然后在python中调用生成加密参数,然后传入post请求,实现爬虫。
逆向过程:
1、搜索参数nonce,会有如下结果:
2、选择任一结果,选择美化代码,找到JS代码中该参数位置。
3、此时很容易看到两个参数的位置,打上断点。注意,nonce参数就是i,而上一行显示i就是j函数
4、在658行处也打上断点,点击调试。显示j函数的链接,点击进去,就找到了j函数的代买,也就是nonce参数的生成原理。
只要有一定java或者js或者C语言经验, 不难看出,这段代码就是随机生成一个由9个数字或字母组成的字符串。
此时我们可以在自己的编译器中(我用Vscode,记事本也可以)新建一个JS文件(如newrank.js),然后直接拷入上段JS代码,这样解决了第一个参数。(也可以自己用python直接写一个随机函数生成)
5、继续调试,寻找第二个参数xyz的加密原理。
xyz就是d函数,通过调试得知,d函数就是b函数,如下图。
我们点击进入b函数,结果如下
其实这个函数的作用就是把参数进行md5加密,仅此而已!!! 如果看不懂,也可以直接把JS代码抠出来,毕竟就是一个函数。抠的时候,千万要抠全了, 否则是无效的函数。亲手测试下就知道这个大坑了,尤其是新手。我们把这个函数的JS代码复制出来,加到上面新建的 JS文件里面,然后保存。
6、还要找到生成参数xyz的加密函数的参数。重复刚才的调试,可以看到,生成xyz的d函数的参数为h,而上一行显示参数h由'/xdnphb/index/getMedia?AppKey=joker&keyword=&pageNumber=页码&pageSize=10' 和字符串'&nonce='和nonce参数拼接而成。
至此,我们找到了参数生成函数,以及其参数的来源。
接下来我们只需要调用我们新建的js文件里的相应函数,生成加密参数,然后传入post请求,即可完成爬虫。
要注意调用js代码的方法,具体请见完整爬虫代码。
import requests
import pprint,time
import execjs
import hashlib
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64;` rv:47.0) Gecko/20100101 Firefox/47.0",
"referer": "https://www.newrank.cn/public/news.html?",
}
with open(r'D:\pythoncode\JS\newrank.js',encoding='utf-8') as f:
#上面这个newrank.js文件就是我们新建的js文件,里面放入了从网站JS源码抠出的两个函数。
js=f.read()
ctx=execjs.compile(js)
for page in range(1,21):
nonce=ctx.call('j') #调用JS代码中的函数生成第一个加密参数nonce
xyz=f'/xdnphb/index/getMedia?AppKey=joker&keyword=&pageNumber={page}&pageSize=10&nonce=' + nonce
xyz=ctx.call('b',xyz) #调用JS代码中的函数生成第二个加密参数xyz
#xyz参数也可以直接用python的MD5加密实现
# xyz=hashlib.md5(xyz.encode(encoding='utf-8')).hexdigest()
data = {
'keyword': '',
'pageNumber': str(page),
'pageSize': '10',
'nonce': nonce,
'xyz': xyz
}
# print(nonce, xyz)
response = requests.post('https://www.newrank.cn/xdnphb/index/getMedia', headers=headers, data=data)
print(response.status_code)
# print(response.text)
response_data=response.json()['value']
# pprint.pprint(response_data)
for item in response_data:
print('资讯标题:',item['title'],'发布时间:',item['public_time'])
看到如下的爬取结果如下,心里还是挺爽的。欢迎大家留言交流 !需要那个JS代码的也可以留言。