群里的初级工程师求助说,要采集采招数据,必须给他安排上 Y26
📢📢📢📢📢📢
💗 你正在阅读 【梦想橡皮擦】 的博客
⛳️ Python 采招实战场景
本篇属于加更博客,源自群友的一个小需求,希望采集一下某【采招】网站数据,目标站点地址如下:
Base64 加密:aHR0cHM6Ly9zZWFyY2guYmlkY2VudGVyLmNvbS5jbi9zZWFyY2g/a2V5d29yZHM9JUU1JTg1JUFDJUU1JTg1JUIxJUU4JUI1JTg0JUU2JUJBJTkwJUU0JUJBJUE0JUU2JTk4JTkzJmRpcXU9MyZtb2Q9MCZwYWdlPTQ=
简述一下操作流程:
- 首先我们通过开发者工具,检查数据接口的请求参数与响应内容,查看加密位置;
- 然后获取加密参数,并尝试直接搜索,如果能直接定位,任务直接完成;
- 添加接口断点,反复测试,确定加密逻辑;
- 将 JS 代码翻译为 Python,如果加密逻辑复杂,直接 扣 JS 源码。
捕获的请求逻辑如下所示:
- 请求网址: https://Python 爬虫脱敏/search/GetSearchProHandler.ashx
- 请求方法: POST
- 请求参数:from,guid,location,token,next_token,keywords,diqu,mod
其中只有 guid 有一点点加密逻辑在,既然请求无太多加密逻辑,那群友反馈时说无法解析,就是响应的问题了
打开响应面板,得到如下内容:
果然响应内容是加密的,由历史经验可以知道,这段大概率又是 AES 加密,只是现在还不知道密钥,需要通过断点进行调试。
在请求发送的位置添加断点,点击任意分页,只要能停住,我们的程序就完成了一半。
在断点调试堆栈中,看到 jq_search
函数,可以大胆的点击,估计服务器响应的解码工作就在该函数中。
注意下图中,由于请求中无加密参数,所以关注响应数据逻辑,即下述 success
函数。
接下来在 method.bindSearchData(index, res, params, callback);
处添加断点,接着运行请求,代码会停在 success
处。
成功找到 AES 加密的位置。
加密逻辑如下所示:
var nContent = CryptoJS.AES.decrypt(str, variate.key, {
iv: variate.aceIV,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.ZeroPadding,
});
其中除了 padding 是新的形式外,其余都是熟悉的信息。
variate.key
和 variate.aceIV
通过检索进行获取。
//页面基础变量
var variate = {
key: { "words": [863652730, 2036741733, 1164342596, 1782662963], "sigBytes": 16 },
aceIV: { "words": [1719227713, 1314533489, 1397643880, 1749959510], "sigBytes": 16 },
xgGjcArray: [],
xgGjcIndex: 0,
isPageLoad: false//是否为页码跳转
}
接下来我们截取 str(响应的加密串),然后使用 Python 解析。
将 key 和 aceIV 还原成字符串
这个步骤使用网站自带的加密还原即可。
CryptoJS.enc.Utf8.stringify({
words: [863652730, 2036741733, 1164342596, 1782662963],
sigBytes: 16,
});
运行结果如下所示,得到 key
值为 3zKzyf6eEfuDjAG3
。
相同的办法把 IV
也获取到,值为 fyUANZ0qSNZhhNCV
。
下面就是还原最终的那段加密 JS 了。
这里用到的逻辑是,通过 Python 实现 AES 加密解密(ZeroPadding)。
下述代码仅实现解密逻辑
import base64
from Crypto.Cipher import AES
def AES_Decrypt(key, data):
iv = 'fyUANZ0qSNZhhNCV'
data = data.encode('utf8')
encodebytes = base64.decodebytes(data)
# 加密数据转换位 bytes 类型数据
cipher = AES.new(key.encode('utf8'), AES.MODE_CBC, iv.encode('utf8'))
text_decrypted = cipher.decrypt(encodebytes)
# 补位
text_decrypted = text_decrypted.rstrip(b'\0')
text_decrypted = text_decrypted.decode('utf8')
return text_decrypted
# 加密 key
key = '3zKzyf6eEfuDjAG3'
enc_text = 'c5k4assk4I/VDW+UuydxKwiUqMnM4lw…… 服务器返回的加密字符串~'
t_decrypted = AES_Decrypt(key, enc_text)
print(t_decrypted)
运行代码,得到解析之后的 JSON 字符串,答应群友的任务完成啦。
📣📣📣📣📣📣
右下角有个大拇指,点赞之后欢迎加入我们!
- 点赞
- 收藏
- 关注作者
评论(0)