爬虫分享
1、爬虫科普
视频发送于2024-10-27 14
_50.mp4
全屏预览下载附件
所以 爬虫 其实是非常 可"刑" 可"铐" 的。
2、逆向方法
算法还原
补环境
无头浏览器(自动化)
rpc
参数生成速度:算法还原 > 补环境 > rpc > 无头浏览器
逆向破解速度:无头浏览器 > rpc > 补环境 > 算法还原
2.1、算法还原
算法还原 就是 找到具体的加密函数入口,一步一步打断点 日志 跟进 定位到具体的加密位置,从而还原加密算法,算法还原是难度非常高的。我有时候 跟堆栈信息,跟着跟着就找不到北了。而且在跟进函数,会有大量的循环、条件判断、异步操作以及js混淆。同时要非常了解加密方式,能够根据生成的参数,能够判断是什么加密方式。
2.2、无头浏览器
无头浏览器 就是 模拟正常人的操作,打开浏览器,进入某个页面,等页面渲染后,获取页面上的元素信息。这肯定是要比直接爬取接口慢的,但是相对简单。以及无头浏览器与正常人操作浏览器,还是有区别的。如果请求过多的话,会弹出验证窗口,机器人验证的页面。
2.3、rpc
rpc方式 就是 注入或者修改js源文件,搞一个websokect的服务器,在js源文件里注入 websocket的客户端与websokect的服务器通讯。服务器将参数传给客户端,客户端调用加密函数,将加密的参数返回给服务器。
2.4、补环境
补环境 就是 找到具体的加密函数入口,把加密函数扣下来,缺什么参数或者环境,从浏览器中获取加上,再将加密函数暴露出来以供调用使用。因为自己扣下来的js文件,需要要用node.js执行,但是node.js没有浏览器的环境,比如:Document等。所以就需要我们将浏览器的环境补齐,让js代码,以为就是在真正的浏览器里。补环境难度不是很高,但是需要耐心与细心。
接下来,我会主要介绍一下补环境的一些通用的思路和手段。
3、最棒的web逆向工具
那就是浏览器!!
3.1、两个搜索
快速定位接口:ctrl+f 弹出搜索框
举个栗子:如何快速的找到笔记详情是哪个接口返回
将接口右键复制为curl后,可以用在线网站将curl转换成对应的语言的实现,网站如下:
https://curlconverter.com/python/
找到接口后,我们就需要分析
哪些参数可以写死
哪些是请求参数
拿些是加密的参数
http请求,能存参数的位置,一共就3个
url路径上
body请求体
header请求头
快速定位加密函数:
先来讲一下,js的参数赋值的方式
// 第一种
var header = {
"X-s": "token"
xs: "token"
}
// 第二种
header["X-s"] = "token"
// 第三种
header.xs = "token"
所以,搜索加密函数位置,可以这几种:
{sign} =
["{sign}"]
{sign} :
小红书的字段存在"-",所以只能用第二种搜索方式
对可疑的地方都加上断点,刷新判断在哪断点停下了,这就说明这就是我们要找的位置。
如果无法通过字段名搜索到加密位置的话(说明存在混淆),那么就只能慢慢跟栈,里找到加密位置了(或者解混淆)。
打印一下日志,我们可以看到加密函数是一个全局函数 window._webmsxyw,进入到函数里,将整个页面copy下来。
现在已经找到加密函数的入口。接下来就到了补环境了。
3.2 一些反爬措施
无限debugger:
有些网站进入浏览器的调试控制台,会触发无限debugger
解决办法:https://www.zhangbj.com/p/586.html
参数顺序:
接口请求时参数的顺序,也会导致无法请求成功,所以尽量不要更改顺序。
参数缩进:
以及注意参数的缩进,例如:
{"a": "a", "b": 2}
{"a":"a","b":2}
缩进不同,也会导致无法正确获取响应
ast混淆:
AST混淆(Abstract Syntax Tree Obfuscation)是一种通过修改源代码的抽象语法树(AST)来实现代码混淆的技术,目的是使代码更加难以理解,但不改变程序的实际功能。AST是程序代码的结构化表示,显示了代码的语法结构,类似于代码的"骨架"。
在AST混淆中,攻击者或开发者通过对AST进行各种操作来重构源代码,使得代码的语法结构和逻辑流程变得不那么直观,但仍然能够保持原有的行为。常见的操作包括:
重命名变量和函数:改变变量和函数名为没有意义的名称,从而增加反编译和逆向工程的难度。
改变代码结构:通过修改代码的表达方式(比如通过不同的控制结构替代原来的结构),使得代码逻辑复杂化,但不影响最终的执行效果。
增加冗余代码:插入无效的代码(例如无用的循环、条件语句等),目的是让代码看起来更复杂,迷惑分析者。
改变语法形式:通过替换某些语法结构(比如表达式的顺序、使用不同的语言特性等)使得代码更难理解。
AST混淆的优势在于它不依赖于简单的字符串级别的替换,而是通过语法层面的混淆来增加理解的难度。相比传统的代码混淆方法(如字符串替换、删除注释等),AST混淆更能在保持代码功能不变的同时,增加代码的复杂性和可读性障碍,特别是对静态分析工具和逆向工程人员来说。
解决方案:https://www.52pojie.cn/thread-1913553-1-1.html#50105908_参数分析
4、取之浏览器 用之浏览器
创建好文件:
env.js // 用于填写环境的js代码
source.js // copy下来的js文件
sign.js // 用于导入 env.js 与 source.js 文件 获取生成加密参数
env.js 初始化环境:
window = global
delete global // node.js 特有参数,会检测
delete Buffer // node.js 特有参数,会检测
在运行js脚本之后,显示的报错信息,我们并不知道,具体是哪个对象的缺少参数。
给环境参数添加代理,每次执行get或set的时打印参数信息:
bash
function setProxy(proxyObjs) {
for (let i = 0; i < proxyObjs.length; i++) {
const handler = `{
get: function(target, property, receiver) {
console.log("方法:", "get ", "对象:", "${proxyObjs[i]}", " 属性:", property, " 属性类型:", typeof property, ", 属性值:", target[property], ", 属性值类型:", typeof target[property]);
return target[property];
},
set: function(target, property, value, receiver) {
console.log("方法:", "set ", "对象:", "${proxyObjs[i]}", " 属性:", property, " 属性类型:", typeof property, ", 属性值:", value, ", 属性值类型:", typeof target[property]);
return Reflect.set(...arguments);
}
}`;
eval(`try {
${proxyObjs[i]};
${proxyObjs[i]} = new Proxy(${proxyObjs[i]}, ${handler});
} catch (e) {
${proxyObjs[i]} = {};
${proxyObjs[i]} = new Proxy(${proxyObjs[i]}, ${handler});
}`);
}
}
setProxy(["window", "location", "navigator", "document", "history", "screen", "localStorage"])
加上代理后一目了然:
缺少 createElement 参数,所以这个是什么东东呢?可以使用下面的网站搜
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript
我们就需要将缺少的环境补上
主要就是把一些undefined的值补上。
还有就是每次补完undefined,重新运行一下,可能又会出现新的undefined。
注意:对于一些,有具体参数的值,一定要与浏览器的环境里一致。如果浏览器里的打印出来的是undfiend,那么也就无需补了,因为实际上就是undefined。
5、逆向完成 现在才是开始
怎样批量的把数据爬取下来,我感觉是比逆向难度还要高的。
还有一点,反爬措施,只能延缓,不能阻止爬虫。
我总结了一些反爬措施
1、ip限流\封禁
2、账号(cookie)限流\封禁
3、人机行为
4、脏数据
5、响应数据加密
对于 1、2点来说,就是控制爬虫的频率,也可以采用ip池、cookie池,提升爬取速度。
但是我还是不建议这样做,如果搞的太过分了,影响网站正常使用,这就变成了doss攻击了,这就要叔叔请喝茶了。
对于人机行为,主要避免一些固定行为,比如爬取到到笔记列表,就依次从头遍历,对于正常人来说,没人会从头挨个看到尾,所以要打乱响应的笔记顺序,并添加随机睡眠时间。
对于脏数据,说明获取到加密参数,还是不对。不排除,是请求频率太快导致响应脏数据
响应数据加密,加密一定是可逆的,否则前端怎么展示信息呢。
无论是对称加密,还是非对称加密,解密密钥一定存在js文件或者某个接口中。
6、补环境入门网站
补环境,其实还是很好理解的。就是让检测环境的代码通过,让js代码认为就是在浏览器里运行的,所以补环境其实是一个要有耐心和细心的事情。但是在实际操作中,会有一些意想不到的问题。还是需要多多练习。
如果想体验一下补环境。这里我推荐一个入门补环境的网站,某乎,这个网站的环境检测很有意思,基本上就是补一个环境,再次运行又会出现一个新的环境检测参数。感兴趣的可以试试。
附上教程视频: