大厂在用的反爬虫手段

Posted pythonkiteman

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了大厂在用的反爬虫手段相关的知识,希望对你有一定的参考价值。

有人说爬虫爬天爬地爬空气,网站怎么有效保护密码?(有哪些反爬虫手段可以保护密码)
其实,SVG 映射可有效保护密码。

SVG 映射

SVG 用于描述二维矢量图形的一种图形格式。它基于 XML 描述图形,对图形进行放大或缩小操作都不会影响图形质量。矢量图形的这个特点使得它被广泛应用在 Web 网站中。 下面我们要了解的反爬虫手段正是利用 SVG 实现的,这种反爬虫手段用矢量图形代替具体的文字,不会影响用户正常阅读,但爬虫程序却无法像读取文字那样获得 SVG 图形中的内容。因为 SVG 中的图形代表的也是一个个文字,所以在使用时必须在前端或后端将真实的文字与对应的 SVG 图形进行映射和替换,这种反爬虫手段被称为 SVG 映射反爬虫。

SVG 映射实战

SVG 映射反爬虫示例

网址:http://www.porters.vip/confusion/food.html反爬虫练习。 任务:爬取美食商家评价网站页面中的商家联系电话、店铺地址和评分数据。

评分数据中口味分数元素定位,奇怪的是根据页面显示内容,html 代码中评分应该是 8.7 才对,但实际上我们看到的却是:

<span class="item">口味:<d class="vhkjj4"></d>.7</span>

HTML 代码中有数字 7 和小数点,但就是没有 8 这个数字,似乎数字 8 的位置被 d 标签占据。而商家电话号码处的显示就更奇怪了,一个数字都没有。商家电话对应的 HTML 代码如下(到底怎么回事):

<div class="col more"> 
        电话:
   <d class="vhkbvu"></d> 
   <d class="vhk08k"></d> 
   <d class="vhk08k"></d> 
   <d class="">-</d> 
   <d class="vhk84t"></d> 
   <d class="vhk6zl"></d> 
   <d class="vhkqsc"></d> 
   <d class="vhkqsc"></d> 
   <d class="vhk6zl"></d> 
</div>

包含很多的 d 标签,难道它使用 d 标签进行占位,然后用元素进行覆盖吗?我们可以将 d 标签的数量和数字的数量进行对比,发现它们的数量是相同的(8个),也就是说一对 d 标签代表一个数字。 每一对 d 标签都有 class 属性,有些 class 属性值是相同的,有些则不同。我们再将 class 属性值与数字进行对比,看一看能否找到规律。

猛然发现,从class 属性值和数字的对比可以看出,class 属性值和数字是一一对应的,如属性值 vhk08k 与数字 0 对应。根据这个线索,我们可以猜测每个数字都与一个属性值对应。

数字与属性值对应关系 浏览器在渲染页面的时候就会按照这个对应关系进行映射,所以页面中显示的是数字,而我们在 HTML 代码中看到的则是这些 class 属性值。浏览器在渲染时将 HTML 中的 d 标签与数字按照此关系进行映射,并将映射结果呈现在页面中。我们的爬虫代码也可以按照同样的逻辑实现映射功能,在解析 HTML 代码时将 d 标签的 class 属性值取出来,然后进行映射即可得到页面中显示的数字。如何在爬虫代码中实现映射关系呢?实际上网页中使用的是 “属性名数字” 这种结构,Python 中内置的字典正好可以满足我们的需求。可以用 Python 代码测试一下,代码如下:

#定义映射关系
mappings = {'vhk08k': 0, 'vhk6zl': 1, 'vhk9or': 2, 
   'vhkfln': 3, 'vhkbvu': 4, 'vhk84t': 5, 
   'vhkvxd': 6, 'vhkqsc': 7, 'vhkjj4': 8, 
   'vhk0f1': 9} 
#HTML 中得到的属性值
html_d_class = 'vhkvxd' 
#将映射后的结果打印输出
print(mappings.get(html_d_class))

这段代码的逻辑是:首先定义属性值与数字的映射关系,然后假设一个 HTML 中 d 标签的属性值,接着将这个属性值的映射结果打印出来。代码运行后得到的结果为:

6
运行结果说明映射这种方法是可行的。接着我们试一试将商家的联系电话映射出来:

#定义映射关系
mappings = {'vhk08k': 0, 'vhk6zl': 1, 'vhk9or': 2, 
            'vhkfln': 3, 'vhkbvu': 4, 'vhk84t': 5, 
            'vhkvxd': 6, 'vhkqsc': 7, 'vhkjj4': 8, 
            'vhk0f1': 9} 
#商家联系电话 class 属性
html_d_class = ['vhkbvu', 'vhk08k', 'vhk08k', 
                '', 'vhk84t', 'vhk6zl', 
                'vhkqsc', 'vhkqsc', 'vhk6zl'] 

phone = [mappings.get(i) for i in html_d_class] 
#将映射后的结果打印输出
print(phone)

运行结果为:

[4, 0, 0, None, 5, 1, 7, 7, 1]
我们使用映射的方法得到了商家联系电话,说明 SVG 映射反爬虫已经被我们绕过了。

小结

本文示例所用的反爬虫手段,即使借助渲染工具也无法获得 “见到” 的内容。SVG 映射反爬虫利用了浏览器与编程语言在渲染方面的差异,以及 SVG 与 CSS 定位这样的前端知识。如果爬虫工程师不熟悉渲染原理和前端知识,那么这种反爬虫手段就会带来很大的困扰。

以上是关于大厂在用的反爬虫手段的主要内容,如果未能解决你的问题,请参考以下文章

爬虫进阶常见的反爬手段和解决方法(建议收藏)

反反爬虫的技术手段都有哪些?

那些年绕过的反爬手段

爬虫抓取技术

利用selenium进行爬虫时,防止js检测驱动的方法

selenium的基本使用