打码打码Python爬虫,某省建筑市场请求地址参数分析,手慢无爬虫 Y8
📢📢📢📢📢📢
哈喽!大家好,我是 【梦想橡皮擦】,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 错误,此时可以断定,请求地址中的 appKey
,time
,sign
参数必然有用,所以接下来我们去分析其逻辑即可。
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了
- 点赞
- 收藏
- 关注作者
评论(0)