在学会基本的爬虫操作后,网页抓取之路并不顺畅,因为js的盛行,现在大多数数据都被加密了,遂开始了逆向的学习。这篇文章分享我自己实操的第一个案例,教程可以参考b站教学
首先观察页面https://www.qimingpian.com/innovate
在点击加载更多之后注意到recommendeditemlist这个包,点击预览可以看到其中encrypt_data这个数据,这个就是加密过后的企业数据。
使用post请求可以得到一样的结果:
import requests
headers = {
'accept': 'application/json, text/plain, */*',
'accept-language': 'zh-CN,zh;q=0.9',
'cache-control': 'no-cache',
'content-type': 'application/x-www-form-urlencoded',
'origin': 'https://www.qimingpian.com',
'pragma': 'no-cache',
'priority': 'u=1, i',
'sec-ch-ua': '"Chromium";v="124", "Google Chrome";v="124", "Not-A.Brand";v="99"',
'sec-ch-ua-mobile': '?0',
'sec-ch-ua-platform': '"Windows"',
'sec-fetch-dest': 'empty',
'sec-fetch-mode': 'cors',
'sec-fetch-site': 'cross-site',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36',
}
data = {
'page': '2',
'num': '20',
'sys': 'vip',
'keywords': '',
'unionid': '',
}
response = requests.post('https://vipapi.qimingpian.cn/search/recommendedItemList', headers=headers, data=data).json()
print(response)
以下是输出结果:
由于数据中已经带有明显、规范的关键词:encrypt_data(中文即编译过后的数据),我们可以直接利用关键字进行搜索,找到包含js加密算法的文件:
搜索出来两个文件,一个js,一个无后缀名,是一个接口文件。选择js文件进入到sources板块。
按ctrl+f进行搜索:
一共有6个结果,我们需要的是一个由加密方法包裹encrypt_data的结果,由此可以找到是最后一个,并在此设置断点。
从外到内设置两个断点,并刷新页面:
这时可以将Object(d.a)(t.encrypt_data)复制到console(控制台)进行输出来检查一下:
结果是我们需要的解密好的数据,这个时候再将Object(d.a)输入console得到方法:
点击进去来到方法的定义处进行复制,创建一个js文件夹并将其粘贴进去,这是解密的主函数。
这个时候我们来调试js文件:
首先随意使用一组encrypt_data,可以再console中输入t.encrypt_data获取。
接着试运行js文件:
结果如下:
报错显示o没有被定义,现在来填补o。
在s函数里找到o,并打上断点:
手动运行运行到断点处,并且在控制台输入o来获得o定义:
同样将其粘贴到js文件中。
再次运行js文件,获得报错:
解决办法同上。(但要注意此处的a是a.a.decode这个方法)
获得后将其改名以便使用。
再次运行js文件获得报错:
同样的方法获取到f是一个固定字符串: /[\t\n\f\r ]/g, 则在函数中定义这个字符串即可:
再次运行获得报错:
l的处理思路同上。。。
处理完之后会获得正确信息:
可见我们的js文件已经配置成功,可以正确的解译数据了,现在与python进行交互:
在js文件中去掉多余代码:
添加代码:(不然可能报错说JSON未被定义)
if (typeof JSON === 'undefined') {
var JSON = {
parse: function(s) { return eval('(' + s + ')'); },
stringify: function(v) { return JSON.stringify(v); }
};
}
以下是python代码:
import requests
import execjs
headers = {
'accept': 'application/json, text/plain, */*',
'accept-language': 'zh-CN,zh;q=0.9',
'cache-control': 'no-cache',
'content-type': 'application/x-www-form-urlencoded',
'origin': 'https://www.qimingpian.com',
'pragma': 'no-cache',
'priority': 'u=1, i',
'sec-ch-ua': '"Chromium";v="124", "Google Chrome";v="124", "Not-A.Brand";v="99"',
'sec-ch-ua-mobile': '?0',
'sec-ch-ua-platform': '"Windows"',
'sec-fetch-dest': 'empty',
'sec-fetch-mode': 'cors',
'sec-fetch-site': 'cross-site',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36',
}
data = {
'page': '2',
'num': '20',
'sys': 'vip',
'keywords': '',
'unionid': '',
}
response = requests.post('https://vipapi.qimingpian.cn/search/recommendedItemList', headers=headers, data=data).json()
decrypt_data = execjs.compile(open('d://pythonproject/js/2.js', 'r', encoding='utf-8').read()).call('s', response['encrypt_data'])
for i in decrypt_data['list']:
print(i)
输出结果为:
最后成功获得数据。