写点什么

群里的初级工程师求助说,要采集采招数据,必须给他安排上

作者:梦想橡皮擦
  • 2022 年 7 月 17 日
  • 本文字数:1624 字

    阅读完需:约 5 分钟

📢📢📢📢📢📢💗 你正在阅读 【梦想橡皮擦】 的博客👍 阅读完毕,可以点点小手赞一下🌻 发现错误,直接评论区中指正吧📆 橡皮擦的第 <font color=red>621</font> 篇原创博客


⛳️ Python 采招实战场景

本篇属于加更博客,源自群友的一个小需求,希望采集一下某【采招】网站数据,目标站点地址如下:


Base64 加密:aHR0cHM6Ly9zZWFyY2guYmlkY2VudGVyLmNvbS5jbi9zZWFyY2g/a2V5d29yZHM9JUU1JTg1JUFDJUU1JTg1JUIxJUU4JUI1JTg0JUU2JUJBJTkwJUU0JUJBJUE0JUU2JTk4JTkzJmRpcXU9MyZtb2Q9MCZwYWdlPTQ=



简述一下操作流程:


  1. 首先我们通过开发者工具,检查数据接口的请求参数与响应内容,查看加密位置;

  2. 然后获取加密参数,并尝试直接搜索,如果能直接定位,任务直接完成;

  3. 添加接口断点,反复测试,确定加密逻辑;

  4. 将 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.keyvariate.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 base64from 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
# 加密 keykey = '3zKzyf6eEfuDjAG3'enc_text = 'c5k4assk4I/VDW+UuydxKwiUqMnM4lw…… 服务器返回的加密字符串~'
t_decrypted = AES_Decrypt(key, enc_text)print(t_decrypted)
复制代码


运行代码,得到解析之后的 JSON 字符串,答应群友的任务完成啦。



📣📣📣📣📣📣右下角有个大拇指,点赞之后欢迎加入我们!


发布于: 刚刚阅读数: 3
用户头像

爬虫 100 例作者,蓝桥签约作者,博客专家 2021.02.06 加入

6 年产品经理+教学经验,3 年互联网项目管理经验; 互联网资深爱好者; 沉迷各种技术无法自拔,导致年龄被困在 25 岁; CSDN 爬虫 100 例作者。 个人公众号“梦想橡皮擦”。

评论

发布
暂无评论
群里的初级工程师求助说,要采集采招数据,必须给他安排上_Python_梦想橡皮擦_InfoQ写作社区