文章目录
- 1. 写在前面
- 2. 请求分析
- 3. JS反混淆
- 4. 深度分析
【作者主页】:吴秋霖
【作者介绍】:Python领域优质创作者、阿里云博客专家、华为云享专家。长期致力于Python与爬虫领域研究与开发工作!
【作者推荐】:对JS逆向感兴趣的朋友可以关注《爬虫JS逆向实战》,对分布式爬虫平台感兴趣的朋友可以关注《分布式爬虫平台搭建与开发实战》
还有未来会持续更新的验证码突防、APP逆向、Python领域等一系列文章
1. 写在前面
爬虫一途,艰且险阻。稍有不慎就会令你抓耳挠腮!相信很多爬虫工程师们在职业生涯中遇到过各式各样的反爬虫操作,可以说是五花八门!本期教程难度并不高,但是仍然可以阻拦绝大部分的爬虫操作,赶紧动手跟作者学起来吧!
看似Cookie反爬、实则只是开胃小菜!核心防护在翻页点选验证码验证并生成验证加密参数用以后续翻页请求!
分析目标:
aHR0cDovL3d3dy55bmdwLmNvbS8=
2. 请求分析
一般针对Cookie反爬虫,应该如何判断?这里我们可以尝试清除Cookie记录,点击鼠标右键Replay XHR再次重放请求,如下再次请求无效:
这里我们也可以直接Curl请求到本地终端测试,尝试请求网站,得到如下反馈:
这说明是有Cookie反爬的!初看开局刷新页面那张显示加载动作的图,是不是发现跟那个Cloudflare加载的时候异曲同工之妙~
通过上述分析大概率可以判断该网站对Cookie进行了判断检测,导致爬虫无法正常的流程获取到页面数据,既然是Cookie有问题做了手脚,那么我们先分析Cookie尝试多次测试看看有什么变化,经过测试发现PYCCS是在二次请求中更新的,如下所示:
3. JS反混淆
到了这一步,一般有经验的已经知道该从哪里入手分析了!它这个现象跟我之前做的这个小网站有点相似之处的:某网站搜索接口参数MD5加密又加盐逆向实战分析
它们的相似点就是JS操作的代码放在了请求响应内!并且是混淆过的。就是上面测试请求那块返回的eval(function(…
这里我们拿出来进行一个反混淆,反混淆之后使用AST普通解密来进行还原,如下所示:
var _$ = ["#challenge", "#waf_answer", "#ChallengeForm"];
$(_$[0]).show();
$(function () {
setTimeout(function () {
var x06dd1a = {};
var x0fcad9;
var x08c924 = 38;
var x01c264 = navigator.userAgent.toLowerCase();
x08c924 = x08c924 * 99;
if (x0fcad9 = x01c264.match(/msie ([\d.]+)/)) {
x06dd1a.ie = x0fcad9[1];
} else {
if (x0fcad9 = x01c264.match(/firefox\/([\d.]+)/)) {
x06dd1a.firefox = x0fcad9[1];
} else {
if (x0fcad9 = x01c264.match(/chrome\/([\d.]+)/)) {
x06dd1a.chrome = x0fcad9[1];
} else {
if (x0fcad9 = x01c264.match(/opera.([\d.]+)/)) {
x06dd1a.opera = x0fcad9[1];
} else {
if (x0fcad9 = x01c264.match(/version\/([\d.]+).*safari/)) {
x06dd1a.safari = x0fcad9[1];
} else {
0;
}
}
}
}
}
x08c924 = x08c924 + 46;
if (x06dd1a.ie || x06dd1a.firefox || x06dd1a.chrome || x06dd1a.opera || x06dd1a.safari) {
x08c924 = x08c924 * 3 + 7;
if (x08c924 < 123) x08c924 = x08c924 + 2345;
var x0b515d = $(_$[1]);
if (x08c924 > 2345) x08c924 = Math.floor(x08c924 / 123);
x0b515d.val(x08c924);
$(_$[2]).submit();
}
}, 1000);
});
上面的代码AST后是无法直接运行的,需要修改一下,修改之后如下:
navigator = {'userAgent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'}
var _$ = ["#challenge", "#waf_answer", "#ChallengeForm"];
var x06dd1a = {};
var x0fcad9;
var x08c924 = 38;
var x01c264 = navigator["userAgent"]["toLowerCase"]();
x08c924 = x08c924 * 99;
if (x0fcad9 = x01c264.match(/msie ([\d.]+)/)) {
x06dd1a.ie = x0fcad9[1];
} else {
if (x0fcad9 = x01c264.match(/firefox\/([\d.]+)/)) {
x06dd1a.firefox = x0fcad9[1];
} else {
if (x0fcad9 = x01c264.match(/chrome\/([\d.]+)/)) {
x06dd1a.chrome = x0fcad9[1];
} else {
if (x0fcad9 = x01c264.match(/opera.([\d.]+)/)) {
x06dd1a.opera = x0fcad9[1];
} else {
if (x0fcad9 = x01c264.match(/version\/([\d.]+).*safari/)) {
x06dd1a.safari = x0fcad9[1];
} else {
0;
}
}
}
}
}
x08c924 = x08c924 + 46;
if (x06dd1a.ie || x06dd1a.firefox || x06dd1a.chrome || x06dd1a.opera || x06dd1a.safari) {
x08c924 = x08c924 * 3 + 7;
if (x08c924 < 123) x08c924 = x08c924 + 2345;
if (x08c924 > 2345) x08c924 = Math.floor(x08c924 / 123);
}
4. 深度分析
截止到这里,上面还原的JS代码中x08c924所计算出来的值就是下面POST请求获取PYCCS需要提交的参数,提交以后可以拿到Set-Cookie中新的Cookie信息,最后访问网站正常!
每一次请求混淆的JS代码是动态生成的,发现变化的地方在数字上所以answer字段所计算出来的结果也是不固定的!
前面的Cookie反爬虫小烟雾弹只是开胃小菜,真正的重头戏在采购板块下相关的信息,这里面的每一项内容在开始翻页之前必须过一个点选验证码,因为后续的翻页请求中携带提交验证检测通过的加密参数,如下所示:
完成首次的验证是后续请求的必要条件!并且在后续过程中会要求不定时验证检测!每一次点选验证通过以后获取captchaCheckId,它就是检测的加密参数!这个地方全局搜索验证码的那个加密参数,然后可以直接找到一个叫做verify的JS文件,分析如下所示:
这里需要注意的是验证码通过验证之后的captchaCheckId参数是有时效性的!测试的话应该是在30分钟内,过期以后会出现验证校验不通过。重新验证即可,如此往复便可顺利进行后续的工作。如下采集所示:
这个小站的话,除了刚开始的Cookie迷惑操作稍微流程绕了一些外,没有太多的难点!但是本文中规中矩的操作并非最优方案!
爬虫之路、条条可通罗马!
好了,到这里又到了跟大家说再见的时候了。创作不易,帮忙点个赞再走吧。你的支持是我创作的动力,希望能带给大家更多优质的文章