方向不对,努力白费。爬虫也是如此。今天分享的案例很能说明问题。
目标:某集团公司采购信息
aHR0cHM6Ly9lYy5taW5tZXRhbHMuY29tLmNuL29wZW4vaG9tZS9wdXJjaGFzZS1pbmZv
浏览器抓包,请求载荷里就一个加密参数param
全局搜索“param:”,有较多结果,尝试搜索"JSON.stringify(",有6条结果。
打上断点,进行调式,很容易找到加密入口位于下面这个encryptLong函数。
跟进encryptLong定义内部,在其return处打上断点,然后翻页或者刷新页面,一步步跟进,可以发现,加密参数param由encrypt函数处理传入的参数A,然后由w函数处理生成。
容易看出参数A就是请求的原始载荷转化成的字符串,如下图 。
跟进上述w函数,可以发现是个简单的函数,调用的都是标准函数,可以直接使用,无需逆向,如下图:
要处理的就是上述encrypt函数。跟进去,发现是另一个js文件的函数,用的是webpack打包的js文件。并且容易看出该函数内部调用了三个非标准函数,是需要解决的。
此时,如果单独扣这个三个函数,会非常的吃力不讨好,总是缺少各种函数。
我最初在这里浪费了很长的时间,最后能得到加密结果,但是密文长度不对,python请求时时无法成功的。
然后,第二个思路就是构建webpack,通过调用对应的模块达到调用encrypt函数函数的目的。走这个思路,最终是可以拿到结果的,就是花个半小时甚至更长,取决于你对webpack技术的熟练程度。
这个分享一个最简单的方法。注意看,上述encryptLong函数的定义,是以prototype形式出现的。
同时,每次请求都有一个public的包,返回结果是一个字符串,显然是个公钥,所以能想到用到了RSA非对称加密。
想到这里,也能想到了方案:那就是导入jsencrypt模块,然后通过prototype添加encrytLong函数,即可实现加密。最终加密的JS代码截图如下:
注意:
加密前需要处理原始请求载荷对象(即下图python的字典),
包括添加sign,添加时间戳。要使用下图的b函数,需要抠出来,当然也可以直接手动添加到对象属性。
sign参数就是本文第二张图的第2442行MD5,可以扣代码u函数,或者使用crypto-js库。
以下是python代码:
import requests
import execjs
import time
import json
def get_pubkey():
cookies = {
'SUNWAY-ESCM-COOKIE': '87e7733f-33b7-4477-92b4-daa17e4d74df',
}
headers = {
'Accept': 'application/json, text/plain, */*',
'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive',
# 'Content-Length': '0',
# 'Cookie': 'SUNWAY-ESCM-COOKIE=87e7733f-33b7-4477-92b4-daa17e4d74df',
'Origin': 'https://ec.minmetals.com.cn',
'Pragma': 'no-cache',
'Referer': 'https://ec.minmetals.com.cn/open/home/purchase-info',
'Sec-Fetch-Dest': 'empty',
'Sec-Fetch-Mode': 'cors',
'Sec-Fetch-Site': 'same-origin',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36',
'sec-ch-ua': '"Not_A Brand";v="99", "Google Chrome";v="109", "Chromium";v="109"',
'sec-ch-ua-mobile': '?0',
'sec-ch-ua-platform': '"Windows"',
}
response = requests.post('https://ec.minmetals.com.cn/open/homepage/public', cookies=cookies, headers=headers)
return response.text
cookies = {
'SUNWAY-ESCM-COOKIE': '87e7733f-33b7-4477-92b4-daa17e4d74df',}
headers = {
'Accept': 'application/json, text/plain, */*',
'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive',
'Content-Type': 'application/json',
# 'Cookie': 'SUNWAY-ESCM-COOKIE=87e7733f-33b7-4477-92b4-daa17e4d74df',
'Origin': 'https://ec.minmetals.com.cn',
'Pragma': 'no-cache',
'Referer': 'https://ec.minmetals.com.cn/open/home/purchase-info/?tablndex=0',
'Sec-Fetch-Dest': 'empty',
'Sec-Fetch-Mode': 'cors',
'Sec-Fetch-Site': 'same-origin',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36',
'sec-ch-ua': '"Not_A Brand";v="99", "Google Chrome";v="109", "Chromium";v="109"',
'sec-ch-ua-mobile': '?0',
'sec-ch-ua-platform': '"Windows"',
}
ctll=execjs.compile(open('./wukang3.js','r',encoding='utf-8').read())
for page in range(1,5):
data = {"inviteMethod":"","businessClassfication":"","mc":"","lx":"ZBGG","dwmc":"","pageIndex":page}
# print(data)
params=ctll.call('get_param',data,get_pubkey())
print(params)
json_data = {
'param': params
}
response = requests.post(
'https://ec.minmetals.com.cn/open/homepage/zbs/by-lx-page',
cookies=cookies,
headers=headers,
json=json_data,
)
print(response.status_code)
print(response.text)
爬取的结果如下:
如需js代码,请留言。
欢迎大家批评指正!