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

举报
梦想橡皮擦 发表于 2022/04/30 21:29:05 2022/04/30
【摘要】 📢📢📢📢📢📢💗 你正在阅读 【梦想橡皮擦】 的博客 ⛳️ Python 采招实战场景本篇属于加更博客,源自群友的一个小需求,希望采集一下某【采招】网站数据,目标站点地址如下:Base64 加密:aHR0cHM6Ly9zZWFyY2guYmlkY2VudGVyLmNvbS5jbi9zZWFyY2g/a2V5d29yZHM9JUU1JTg1JUFDJUU1JTg1JUIxJUU4J...

📢📢📢📢📢📢
💗 你正在阅读 【梦想橡皮擦】 的博客

⛳️ 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 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 字符串,答应群友的任务完成啦。

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

【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。