再记一次爬取数据过程
本帖最后由 潇洒的吸血鬼 于 2021-8-10 10:13 编辑# 爬虫(Request参数加密)
### 目标网站
某潮流网购社区
### 目标
获取商品信息
### 断点调试问题
使用chrome打开devtools工具会不断触发断点
解决办法如图所示,在触发断点行首右键,选择Add Conditional breakpoint,写入false然后回车。即可解决断点不断触发问题
### 分析网络请求
打开Network视图,经过分析获取数据请求是从
api/v1/h5/index/fire/flow/product/detail这个接口获取的
经过分析发现请求参数对象中有sign字段
猜测是作为数据签名信息一起发送给后台服务用于验证请求的合法性
### 导出HAR文件
由于暂时不清楚,是由那个js文件发送的请求,以及处理的数据
所以选择下载HAR文件进行全文检索
(HAR,即HTTP存档格式(HTTP Archive format)是一种JSON格式的存档文件格式,用于记录网页浏览器与网站的交互过程。文件扩展名通常为.har)
### 获取加密方法
下载HAR文件后使用编辑器打开
由于加密参数为sign,所以直接搜索(sign=),(sign:)等给sign字段赋值的字符串
首先排除(sign=),其次排除(sign =)
然后在搜索(sign:)时发现如下代码
向上查找,发现此代码来自static/js/index.a0a63867.js文件
导出此js文件或者直接从HAR文件中复制此js文件内容保存为index.js
由于此文件被压缩过,所以需要格式化一下进行查看
```Bash
npm install js-beautify -g
js-beautify -f index.js -o index.beautify.js
```
使用编辑器打开index.beautify.js
定位到关键代码
发现加密函数如下
```JavaScript
x = n("19e7"),
_ = function() {
var e = arguments.length > 0 && void 0 !== arguments ? arguments : {},
t = "",
n = function(e) {
if (null === e) return "";
if (e instanceof Array) {
var t = "";
return e.forEach((function(e) {
t.length > 0 && (t += ","), t += JSON.stringify(e)
})), t
}
return e instanceof Object ? JSON.stringify(e) : e.toString()
};
return t = Object.keys(e).sort().reduce((function(t, i) {
return void 0 === e ? t : "".concat(t).concat(i).concat(n(e))
}), ""), t += "048a9c4943398714b356a696503d2d36", Object(x["a"])(t)
},
```
方法的参数就是请求接口中除了sign的其他字段列表
方法的处理流程为
1. 遍历参数列表
2. 赋值参数列表给t
3. 给t拼接048a9c4943398714b356a696503d2d36
4. 调用Object(x["a"])(t)
此处的Object(x["a"])(t),可以理解为调用x方法,传入a作为参数,再调用函数的返回值(还是个方法),传入t作为参数进行处理
搜索19e7,找到x方法内容
x方法内容比较复杂,暂时不去理解方法具体过程,只需要弄清楚如何调用即可
### 调用解密方法
经过分析,入口函数是h函数
h函数处理过程中会调用中间的i,o,r,a等函数
分析完成,开始编写测试
### 测试
在webstorm中创建nodejs项目
创建sign.js文件,[文件内容](https://github.com/ggymm/blog/blob/main/sign.js)
执行node sign.js计算sign的值为
和上图Network视图中请求参数的sign的值一致,证明过程没有问题
### 扩展
加密算法需要理解,最好可以翻译成python或者java代码
### 更新
经评论区提醒,加密算法为md5
据此加密方法python版本
```Python
if __name__ == '__main__': s = 'productSourceNamepropertyValueIdsourceNamespuId1268866048a9c4943398714b356a696503d2d36' m = hashlib.md5() m.update(s.encode('utf-8')) print(m.hexdigest()) # dd62392b600362dc334c6ffb5ee54a3d
```
给几个建议哈,善用chrome浏览器的调试功能可能会更方便点:
1. 反调试右键中有个never pass here (不在此处断下),可以直接不断下,此外,右边的最上面,一个白色的有个左斜线的按钮(deactivate breakpoints)可以禁用所有断点(不过可能就不方便调试了)
2. network抓包的时候按快捷键ctrl + F可以直接搜索相关的请求,定位到对应的包后,可以点击对应后方Initiator栏的链接跳转到发出请求的地方
3. source左下角有个一对大括号的图标,点击后可以快速格式化当前代码 这个我刚好昨天看过,定位md5的k表第一个数,直接可以秒破{:17_1068:} 涛之雨 发表于 2021-8-9 18:03
给几个建议哈,善用chrome浏览器的调试功能可能会更方便点:
1. 反调试右键中有个never pass here (不在 ...
非常感谢建议
1. 反调试的,我几种方法都尝试过。最后选的这种适用性比较好,不影响调试也不容易失败
2. 多谢建议,还用不熟练
3. 这个方法在上个帖子里用过了,所以这次选择换了种方式。另外在编辑器里跳转定义会比较稍微方便一些
漁滒 发表于 2021-8-9 18:08
这个我刚好昨天看过,定位md5的k表第一个数,直接可以秒破
牛的,看来我还要继续加油 第一遍没有看懂,继续学习,多谢分享 看了涛之雨大神的回复,感觉受益匪浅啊、大牛就是大牛。 收藏了,慢慢学习,感谢楼主! 潇洒的吸血鬼 发表于 2021-8-9 18:14
非常感谢建议
1. 反调试的,我几种方法都尝试过。最后选的这种适用性比较好,不影响调试也不容易失败
2 ...
感谢分享
继续学习,多谢分享