python简单爬虫
本文最后更新于:2023年8月24日 晚上
通用头部参数
| 名称 | 说明 |
|---|---|
| Cookie | 用户信息,在headers部分,包含登录校验、签名认证才可能需要cookie |
| User-Agent | UA是最基本的headers之一,是浏览器类型,其中包含windows系统信息,html版本和浏览器版本和内核信息 |
| Referer | Referer也是最基本的headers之一——防盗链接,它用来验证你的来源,需要告诉请求地址,是从哪里来的 |
| Origin | 域名,带http协议的是域名 |
| Host | 主机名称 |
| Content-Type | 请求内容的类型 |
| Content-Length | 内容的长度 |
| Connection | 链接方式,TCP的长 短链接 |
| Accept-Language | 语言 |
| Accept-Encoding | 编码 |
| Accept | 获取数据的类型 |
问题一:如何知道cookie有无加密?
通过set-cookie属性判断
私有头部参数
对于私有的头部参数,可能是时间戳或加密的信息,需要在发起程序中搜索对应名称寻找是如何生成的
| 名称 | 说明 |
|---|---|
| sign | 签名,需要解密 |
断点找请求信息
- 复制请求地址(不含网站名,如
/front/search)添加到源代码中的xhr断点中,刷新请求 - 点击下一步或快捷键F9,调试到出现需要的路径(
cacheURL) - 找到请求头(
request),里面所需的字段名就是前端校验的字段名,都需要模拟填充 - 再看到请求配置项(
options)【这步也可以直接在控制台输入options查看】,复制data替换 - 调试完成后删除所有断点
关于接口数据搜索为空
判断原因
先确定是静态数据还是动态数据,静态数据和动态数据搜索失败有以下问题:
静态数据:
- 字体加密问题
动态数据:
- Unicode编码中文问题
- 数据加密问题
判断是否为静态数据:
直接去源代码的静态代码中查找所要的数据,没有就说明数据是动态加载的
判断是否为编码问题:
使用数字去搜索,没有找到数据地址,说明数据经过加密
跟栈调试
跟栈调试主要是为了寻找js的加密函数
具体步骤:
找到请求资源中的发起程序,找到js源代码,对应行打上断点(点击行号),然后刷新浏览器或点击相同获取资源的地址,在渲染出静态页面后,开始通过跳过函数的形式找数据(就是之前看到很长的字符串),看到数据后,放慢速度找解析后的明文数据(找到后可以直接在控制台输入属性名获取值),然后进入源码解析部分打上断点(这里可取消之前的断点),详细查看找到解析函数的本地地址的源代码复制到自己的js中,再次刷新,选择单步调试(F9),查看传入函数的参数信息,配合上下文可找到其中的变量参数
寻找加密函数
加密后的数据data不是为一个正常对象,而是一大串的字符串
要知道的原理:
加密数据要正常在浏览器上显示,肯定在浏览器的js中有解密的操作
加密的数据无法通过xhr断点调试来找到数据
方式一(较为麻烦):
找到最大的数据源,利用发起程序从源代码中一步步找(具体看上面跟栈调试)
方式二(简单):
利用异步请求为JSON交互的原理,先寻找调用过数据接口的js,然后寻找到JSON.parse后面的数据函数即是加密函数,断点后可进入查看
解密操作
找到加密函数后,利用变量参数声明一个环境变量,在加密函数中分析加密算法,如AES
跟栈调试过程中可能会卡住,将调试窗口弹出可缓解
声明环境变量如下:
1
2
3
4window = global
window.c = "3sd&d2"
window.r = "4h@$udD2s"
window.a = "*"
此时的js如下:
1 | |
decrypt 解密的意思,所以这里看到是AES加密算法
安装crypto-js(前端加密常用)包用与AES解密
1npm i crypto-js
导入crypto-js这个包
1 | |
分析加密函数可得,o.a 即是AES解密库cryptoJs,所以替换即可,最后将获取的加密数据放入即可
1 | |
这里的e通过跟栈调试发现为空值,所以不用管
以上就是逆向解密,但是上面的加密数据不够完善,大型网站也不止是abs加密
使用python执行js代码
现有解密函数如下:
1 | |
要在python中使用,完成整体流程,就要使用到PyExecJS这个包下的execjs
安装:
1 | |
引入使用:
1 | |
- 先使用compile创建一个js的文件环境
- 然后使用call去执行里面的函数名,传递参数
- 返回值就是js函数的返回值
如果返回的内容有中文的话,会出现乱码问题,进入报错的文件将encoding修改为’utf8’即可
完整爬取流程(简单aes加密)
main.py
1 | |
main.js(解密函数)
1 | |
常见加密算法
掌握web逆向技术,需要掌握的加密算法有:
- MD5
- AES
- DES
- RSA
- HASH
- ECC
- SHA
MD5加密特征
如下:
1 | |
用数字做混淆的就是MD5加密
响应数据为纯json渲染
与ajax数据相比:纯json数据在前面会有数据名,如:mtopjson2({api: ...})
而ajax前面是没有这个字符串的
某案例中的sign解密
在数据源的发起程序中搜索sign,寻找到如下代码段:
1 | |
从这里就可以发现sign这个签名是 h(d.token + "&" + i + "&" + g + "&" + c.data)这段生成的
分析:数据主体加密函数是h,打断点后查看直接获取token的值,扣代码到js,先不管是否是动态数据
看到c.data就要和请求体中的data比较,因为可能不止一个加密,可跳过再次比较,对上之后,在控制台中输入c.data可直接获取
为什么不直接复制,要先在控制台打印再复制:
直接复制会导致其中的引号出现问题,控制台打印出来cv就能用
之后进入h源码中,扣下整个函数后执行代码得到sign值
获取sign值后还需要验证:打断点后获取到i的值(时间戳,看页面上sign值是否和本地得到的sign值相同),相同则解密函数正确
其他小知识
有提示加密的响应数据
比如在预览数据中,有一个isEncrypt属性,那么就可以直接使用这个属性去搜索加密函数
iv属性判断
在加密过程中发现iv属性设置,就是AES加密模型