打码打码Python爬虫,某省建筑市场请求地址参数分析,手慢无爬虫 Y8

举报
梦想橡皮擦 发表于 2022/04/18 16:16:25 2022/04/18
【摘要】 📢📢📢📢📢📢哈喽!大家好,我是 【梦想橡皮擦】,10 年产研经验,致力于 Python 相关技术栈传播 💗 ⛳️ 实战场景本案例是 Python 爬虫 JS 加密分析,其中涉及的站点是建筑市场监管数据,由于风险系数高,所以相关信息全部采用密文。本次爬取的站点:\u6d59\u6c5f\u7701\u5efa\u7b51\u5e02\u573a\u76d1\u7ba1\u516c...

📢📢📢📢📢📢
哈喽!大家好,我是 【梦想橡皮擦】,10 年产研经验,致力于 Python 相关技术栈传播 💗

⛳️ 实战场景

本案例是 Python 爬虫 JS 加密分析,其中涉及的站点是建筑市场监管数据,由于风险系数高,所以相关信息全部采用密文。

  • 本次爬取的站点:\u6d59\u6c5f\u7701\u5efa\u7b51\u5e02\u573a\u76d1\u7ba1\u516c\u5171\u670d\u52a1\u7cfb\u7edf
  • 目标地址:https%3A%2F%2Fjzsc.jst.zj.gov.cn%2FPublicWeb%2Findex.html%23%2Fcompany

目标数据区域如下所示:

经过开发者工具简单分析之后,得到接口地址与参数如下所示:

  • 请求网址: https://Python请求地址/dataexchangeserver/ZJJGManagerWebApi/api/EnterpriseInfo/GetEnterpriseInfo?appKey=一个KEY值&time=时间戳&sign=SIGN值
  • 请求方法: POST

分析一下接口响应头内容,寻找其中重要参数,如下图所示:

请求参数如下所示:

{
  "CertID": "",
  "EndDate": "",
  "Zzmark": "",
  "City": "",
  "pageIndex": 1,
  "pageSize": 10
}

⛳️ 重要参数分析时间

在正式开始前,我们需要编写一个基本代码段,确定数据是否可以一步获取。

import requests

headers = {
    "X-Requested-With": "XMLHttpRequest",
    "Accept": "application/json, text/plain, */*",
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) ……",
    "Host": "从开发者工具获取",
    "Origin": "从开发者工具获取",
    "Referer": "从开发者工具获取"
}
params = {"CertID": "", "EndDate": "", "Zzmark": "", "City": "", "pageIndex": 1, "pageSize": 10}

res = requests.post('https://`Python请求地址`/dataexchangeserver/ZJJGManagerWebApi/api/EnterpriseInfo/GetEnterpriseInfo?appKey=`一个KEY值`&time=`时间戳`&sign=`SIGN值`', headers=headers, json=params, verify=False)
print(res.text)

发送请求之后,直接返回 502 错误,此时可以断定,请求地址中的 appKeytimesign 参数必然有用,所以接下来我们去分析其逻辑即可。

appKey 参数
通过 EnterpriseInfo/GetEnterpriseInfo 关键字建立断点调试。

使用 XHR 断点调试之后发现地址貌似是直接硬编码到参数中的,为了排除这种情况,我们可以反复多次请求数据,查看请求地址是否发生变化。

多次测试之后,得到的结论就是该地址无变化,好神奇的操作  ̄□ ̄|| ,看来从这里是无法解决 JS 加密逻辑了。

此时你可以继续观察请求头,注意上图最下面一行代码,在请求的时候,传入了一个 token 参数,那该值应该就是我们解决问题的突破点了。

将断点打到 token 参数赋值的位置,如下图所示:

分析其逻辑,其中重要参数如下:

  • l:字符串类型,测试得到的值为 timeStamp=1649904805956
  • d.a:测试后发现是一种加密形式。

d.a 对应的内容如下图所示,其中存在一个关键字 AES,有加密经验可以得知应该是一个对称加密。

既然是 AES 加密,那其中就会有 KEY 值,有 IV 值,进一步跟进代码发现如下内容:

加密函数也成功的展示了出来。

function o(e) {
    var t = n.enc.Utf8.parse(e);
    return n.AES.encrypt(t, s, {
        iv: r,
        mode: n.mode.CBC,
        padding: n.pad.Pkcs7
    }).toString()
}

比对着编写 Python 代码即可,完整代码可以加下述卡片获取,部分内容截取如下:

if __name__ == '__main__':
    key = '255B675CDF21B04F923992E0E9F4A498'
    iv = '255B675CDF21B04F'

    a = Encrypt(key=key, iv=iv)
    ts = str(int(time.time() * 1000))
    e = a.aes_encrypt(ts)

加密方法如下所示:

def pkcs7padding(self, text):
    """明文使用PKCS7填充 """
    bs = 16
    length = len(text)
    bytes_length = len(text.encode('utf-8'))
    padding_size = length if (bytes_length == length) else bytes_length
    padding = bs - padding_size % bs
    padding_text = chr(padding) * padding
    self.coding = chr(padding)
    return text + padding_text

def aes_encrypt(self, content):
    """ AES加密 """
    cipher = AES.new(self.key, AES.MODE_CBC, self.iv)
    # 处理明文
    content_padding = self.pkcs7padding(content)
    # 加密
    encrypt_bytes = cipher.encrypt(content_padding.encode('utf-8'))
    # 编码
    result = str(base64.b64encode(encrypt_bytes), encoding='utf-8')
    return result

代码运行结果如下所示:

📣📣📣📣📣📣
🌻 本文如果发现错误,欢迎在评论区中指正哦 💗
这案例,写的佬紧张了,一不留神就OVER了

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

评论(0

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

全部回复

上滑加载中

设置昵称

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

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

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