1、前言
接触网络爬虫已经有两三年了,但其实一直没系统的学习过,都是在偶尔有爬数据需求时在网上找教程,应对一些普通的静态网页或者是没有加密参数的ajax请求时没有问题,但现在各类网站越发注重数据保护,制定了很多反爬虫措施,以至于我现有的那点技术储备面对各种花式反扒虫显得捉襟见肘,痛定思痛,还是要认真系统的学习下相关知识。恰巧最近关注的爬虫大佬王平办了个爬虫攻防大赛,所以就想用这些赛题来练习一下,一是在逆向过程中印证学的一些发爬虫理论知识,二是通过实践提高自己的逆向解析能力。
这个专栏打算写十篇,刚好对应这次比赛里的十道赛题,记录一下自己磕磕绊绊的反爬入门过程,希望写到第十篇的时候我还没从入门到放弃…
2、题目理解
待爬取页面
基本概念:
JavaScript 混淆:对 JavaScript 代码进行复杂化处理,它的目的就是使得 JavaScript变得难以阅读和分析,降低代码可读性
根据这题的名称,可以看出两点:一是这个网页有js混淆,要解析必然要进行反混淆;二是从源码乱码判断网页html源代码应该不那么容易观察。
根据题目内容,初步判断我们要抓取的机票价格数据必然不会洗白白在html源码里等我们,大概率是通过ajax请求来获取数据接口。
基于上述理解开始动手搞事情。
3、逆向(踩坑)分析过程
3.1、初步分析
首先F12打开开发者窗口,刷新一下网页,观察请求的数据。这里第一个坑是调试时会出现debugger,需要右键选择Never pause here,这样之后调试就不会卡在这个页面。
继续观察XHR请求,可以发现数据是通过这个接口请求到的,真是令人惊喜的发现,看来我们距离成功就一步了,只要找到参数m的构造逻辑那这小数据还不是手到擒来!
3.2、当头一棒
明确了要找m的生成逻辑目标后,首先想到的是通过设置XHR断点,找到发生ajax请求时调用的js源文件,然后全局搜索字符串,看看有没有发现。
停在这个js文件这里了,看来加密逻辑应该在这里:
用 ctrl+c+f 快捷键调出搜索框,搜索一下m字符试试。好家伙,不搜不得了,一搜吓一跳,800多个匹配结果,这么搞一个个看得看到猴年马月。大致观察一下,感觉都不像是有加密逻辑的样子啊,但是按我之前的知识结构来看,加密参数的生成逻辑应该就在这里才对,一番思考后,我最终还是没想明白咋回事,还是看答案吧。
看了看其他大佬在微信公众号发的解析过程,我是震惊又懊悔。这加密逻辑怎么能就直接放在html里面呢,这不科学啊!涉及到了我的知识盲区!(以后要好好补)也就是说全面我一番骚操作都没找对路,也怪我没理解透源码乱码这四个字的含义…好嘛,那继续充满干劲的开始扣代码!
3.3、循序渐进
把源码复制出来粘贴到pycharm里看看,大致可以看出是将时间戳通过加密函数处理之后,再做一下字符串拼接什么的最后得到m。那么按照缺什么补什么的原则试着执行一下代码。
先是根据错误提示,找到w和dd两个函数,在源码里找到后粘进来,继续运行
进一步,又发现缺少window.a,继续找到加进来,这里可以看出它是一个乱码字符串,挺长的,但是这里千万不要直接复制粘贴,因为直接复制,导致我后面在即将大功告成时想了半天都没发现为什么所有逻辑都摸清楚了还是会报错!
这里最后我是通过在开发者工具里通过watch变量,查找复制出来的,最后成功解决在html里直接复制导致的可能是编码错误的问题(我猜的)
继续粘贴执行代码跑下去,一路上发现了a、b、c、d、e、f、g、h等一系列的变量缺失,逐个找到放回代码里。值得注意的是window.c的值如果通过函数直接执行会得到18这么一个错误答案,正确的方法是直接在控制台输出c,会到的正确的值,也就是5。
好,小变量搞完了继续跑,这会又报了个新的错误,又是个小坑,这atob是个什么鬼变量,找半天没发现在哪定义的。机智的我百度了一下这个字符串,发现它是浏览器端base64解码函数,对应的还有个btoa是用于base64编码。
下一步在网上找到node js环境下对应的函数,然后把源代码改一下
根据对J函数的运行结果查看,可以发现eval函数里的代码实际上是这样的:
原始代码:
eval(