原全国建筑市场监管公共服务平台接口数据爬取
全国建筑市场监管公共服务平台(四库一平台)接口数据解密
需要爬取建筑市场公司的不良行为记录
进入服务平台页面http://jzsc.mohurd.gov.cn,点击顶部的搜索,发现返回的数据是经过加密的:
1. 寻找返回的数据
既然数据是通过这个 url 返回的, 全局搜索url:
http://jzsc.mohurd.gov.cn/api/webApi/dataservice/query/comp/list?pg=0&pgsz=15
尝试全局模糊搜索 /query/comp/list
,开发者工具切换到sources
页签,CTRL+SHIFT+F进行全局搜索,然后点击进入JS函数,再格式化后的JS文件里面再次CTRL+F搜索:
返回的结果是请求 url /dataservice/query/comp/list
得到的, 打上断点,重新点击页面上的搜索,一步一步调试js代码:
调试过程就不一步一步分析了, 最终定位到, 感觉像我们想要的数据, 进入Console打印一下t
和 e
t 中data 是 最初我们请求http://jzsc.mohurd.gov.cn/api/webApi/dataservice/query/comp/list?pg=0&pgsz=15
所返回的数据e
这其中的数据正是我们想要的数据
2.分析加密方式
既然我们已经知道了数据的加密方式, 那我们就重点分析一下这个地方
其中t.data我们在第一步已经分出来了 使我们第一步请求
http://jzsc.mohurd.gov.cn/api/webApi/dataservice/query/comp/list?pg=0&pgsz=15
得到的结果
那我们重点分析 p函数 的处理过程, 点击进入 p函数, 结果如下:
对数据经过层层加密处理后,调用toString方法, 既然加密函数已经找到,我们就可以编写JS代码了
3.代码实现
我们将函数 p 的代码复制出来, data是加密后返回的数据,我们先复制出来用一下
运行一下项目
报错的原因 , 其中 u
和 d
没有进行初始化 我们寻找一下 u 和 d , 就在函数 p的上方
我们把 u 和 d 添加到代码中
运行项目 进行测试
其中返回的数据 , 正是我们想要的结果
4. Python实现
到这里已经能成功使用JS解密返回的数据了,但是如果实现爬虫自动解析需要使用Python实现:
Python中AES解密可以使用Crypto库实现,具体实现代码如下:
def decrypt(text):
key = 'jo8j9wGw%6HbxfFn'
vi = '0123456789ABCDEF'
# 将请求返回的16进制数据转换为二进制数据
text = binascii.a2b_hex(text)
# 构建解密对象
cipher = AES.new(key.encode('utf8'), AES.MODE_CBC, vi.encode('utf8'))
text_decrypted = cipher.decrypt(text)
unpad = lambda s: s[0:-s[-1]]
text_decrypted = unpad(text_decrypted)
# 去补位
text_decrypted = text_decrypted.decode('utf8')
return text_decrypted
5. 最后基于Python的requests实现了简单的请求+解密代码
# -*- coding: utf-8 -*-
import json
import requests
import binascii
from Crypto.Cipher import AES
def decrypt(text):
key = 'jo8j9wGw%6HbxfFn'
vi = '0123456789ABCDEF'
# 将请求返回的16进制数据转换为二进制数据
text = binascii.a2b_hex(text)
# 构建解密对象
cipher = AES.new(key.encode('utf8'), AES.MODE_CBC, vi.encode('utf8'))
text_decrypted = cipher.decrypt(text)
unpad = lambda s: s[0:-s[-1]]
text_decrypted = unpad(text_decrypted)
# 去补位
text_decrypted = text_decrypted.decode('utf8')
return text_decrypted
if __name__ == '__main__':
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.108 Safari/537.36'
}
# 获取到当前搜索结果, 并解密
data = requests.get(
'http://jzsc.mohurd.gov.cn/api/webApi/dataservice/query/comp/list?pg=0&pgsz=15&total=0&complexname='
, headers=headers).text
res = json.loads(decrypt(data))
print(res)
6. 注意
- 本文参考地址: https://www.cnblogs.com/mingyangliang/p/11875925.html
- 平台具有防爬取策略,频繁爬取会导致封IP,可以使用IP代理,或者设置爬取间隔在1.5s
- 所爬取数据请勿用于非法用途