准备抓取一个网站,但是发现启用DDOS保护,感觉有点麻烦了。
打开浏览器F12,发现要求你等待几秒钟检测浏览器,然后通过302重定向到正确的网页。
我们把上面的代码拆成几个子表达式,就好理解了。
首先是第一个嵌套括号中比如这样的: (+!![]+[]),打开浏览器的 console ,在其中输入 +!![] 回车,可以得到数字 1 。
先不管哪个加号,单独看 !![] 的值,它是布尔值 true 。这是因为 [] 返回的是一个有效的 Array,代表 true ,两次取反,依然是 true 。
而左边的那个加号由于没有提供左操作数,因此它的含义是正数,这里做了一次数字转换,自动把 true 转换成了 1 。
接着往后算,后面是个加号,然后是个 [] 。空的数组,默认是作为字符串处理的。[].toString() 的值为空字符串。前面的 1 加上后面的空字符串,得到一个字符串 "1" 。
知道了原理,可以使用同样的方式算出第二个嵌套括号中的值为数字 2 。
接下来是字符串 "1" 加上数字 2,得到字符串 "12" 。
最左边的加号又做了一次转换,将字符串 "12" 转换成了数字 12 。
所以,这一段看似乱码的代码,只是为了获取一些随机的数字,便于和服务器验证罢了。我判断这些数值都是有意义的,而且和服务器时间关联,用来判断访问网站的是不是标准的浏览器。
打开浏览器F12,发现要求你等待几秒钟检测浏览器,然后通过302重定向到正确的网页。
源码查看
打开
html源码,可以看到主要是下面的这个代码:
还有在
JS中使用到的Element:
源码分享
上面代码的作用,主要是原来判断访问站点的客户端是否是一个真实的浏览器。访问网站主页的时候,首先得到的是一个 503 错误,显示上面的页面内容。然后等待 5 秒,让用户看清楚提示信息,然后再根据得到的随机值东拼西凑计算出另一个值,写入 jschl-answer 中,最后通过 challenge-form 这个表单提交。
提交成功之后, /cdn-cgi/l/chk_jschl 会使用 302 重定向返回真实的网页内容。cgksoUW 是一个随机的名称,pass 那个 input 中包含的值也是一个变化的值。每次进入这个页面,这两个值都会变化。
那么,pass 的值在提交的时候到底是如何计算出来的?
从 f = document.getElementById('challenge-form'); 下面的那段代码可以看出,这个计算无非是对 cgksoUW.bRM 进行一些加乘运算。然后再转成一个 Int 进行提交。关键在于那些看起来莫名其妙的加号、括号和方括号的集合的含义为何?
这是一个简单的障眼法。
让我们看看 cgksoUW.bRM 的初始值,这个表达式的结果等于数字 12
那么,pass 的值在提交的时候到底是如何计算出来的?
从 f = document.getElementById('challenge-form'); 下面的那段代码可以看出,这个计算无非是对 cgksoUW.bRM 进行一些加乘运算。然后再转成一个 Int 进行提交。关键在于那些看起来莫名其妙的加号、括号和方括号的集合的含义为何?
这是一个简单的障眼法。
让我们看看 cgksoUW.bRM 的初始值,这个表达式的结果等于数字 12
我们把上面的代码拆成几个子表达式,就好理解了。
首先是第一个嵌套括号中比如这样的: (+!![]+[]),打开浏览器的 console ,在其中输入 +!![] 回车,可以得到数字 1 。
先不管哪个加号,单独看 !![] 的值,它是布尔值 true 。这是因为 [] 返回的是一个有效的 Array,代表 true ,两次取反,依然是 true 。
而左边的那个加号由于没有提供左操作数,因此它的含义是正数,这里做了一次数字转换,自动把 true 转换成了 1 。
接着往后算,后面是个加号,然后是个 [] 。空的数组,默认是作为字符串处理的。[].toString() 的值为空字符串。前面的 1 加上后面的空字符串,得到一个字符串 "1" 。
知道了原理,可以使用同样的方式算出第二个嵌套括号中的值为数字 2 。
接下来是字符串 "1" 加上数字 2,得到字符串 "12" 。
最左边的加号又做了一次转换,将字符串 "12" 转换成了数字 12 。
所以,这一段看似乱码的代码,只是为了获取一些随机的数字,便于和服务器验证罢了。我判断这些数值都是有意义的,而且和服务器时间关联,用来判断访问网站的是不是标准的浏览器。
方案选择
分析完之后,就要进行技术的选择了。写爬虫自然是首选 Python 。开始,我准备使用 requests 来模拟请求,使用 BeautifulSoup4 来解析得到的 HTML,然后进行资源的下载。但 requests 并不擅于模拟浏览器的行为,也不能执行 Javascript,还需要用 PyV8 等库来执行上面的数据计算,得到最终的 pass 。PyExecJS 可以实现在 Python 环境中调用 Javascript 引擎,支持的引擎有 PyV8 ,Node.js 等等。成功跳过 DDos 防护之后,还需要保持 cookies,构建 heads 。既然计算部分要依赖别的引擎解析 Javascript ,那还不如直接使用 Javascript 来写好了。这就是 Headless Browser 大显身手的时候了。
Headless Browser
Headless Browser ,通俗地来说就是个无界面且完整功能的浏览器。目前最流行的 Headless Browser 框架非 PhantomJS 莫属。它是基于 WebKit 开发的,想要整个网页截图神马的(再长也不怕!)用它就最好了。不过,用 PhantomJS 保存网页中的图片 还真是有点麻烦。由于上面的 DDOS 防护的存在,每个单独的图像文件依然存在防护,所以不能拿到地址后直接下载,必须使用浏览器来浏览这个图片。于是我选择了另一个框架 SlimerJS ,它和 PhantomJS 功能基本一致,API 也基本一致,所不同的就是它使用 Mozilla Firefox 的 Gecko 引擎。或者选择
Qt编写一个简单的浏览器,一样可以解决。- 获取链接
- X
- 电子邮件
- 其他应用
- 获取链接
- X
- 电子邮件
- 其他应用



评论
发表评论