SVG 映射反爬虫
很多人学习python,不知道从何学起。
很多人学习python,掌握了基本语法过后,不知道在哪里寻找案例上手。
很多已经做案例的人,却不知道如何去学习更加高深的知识。
那么针对这三类人,我给大家提供一个好的学习平台,免费领取视频教程,电子书籍,以及课程的源代码!
QQ群:1097524789
SVG 是用于描述二维矢量图形的一种图形格式。它基于 XML 描述图形,对图形进行放大或缩小操作都不会影响图形质量。矢量图形的这个特点使得它被广泛应用在 Web 网站中。
接下来我们要了解的反爬虫手段正是利用 SVG 实现的,这种反爬虫手段用矢量图形代替具体的文字,不会影响用户正常阅读,但爬虫程序却无法像读取文字那样获得 SVG 图形中的内容。由于 SVG 中的图形代表的也是一个个文字,所以在使用时必须在后端或前端将真实的文字与对应的 SVG 图形进行映射和替换,这种反爬虫手段被称为 SVG 映射反爬虫。
6.3.1 SVG 映射反爬虫绕过实战
示例 6:SVG 映射反爬虫示例。
网址:http://www.porters.vip/confusion/food.html。
任务:爬取美食商家评价网站页面中的商家联系电话、店铺地址和评分数据,页面内容如图 6-15
所示。
图 6-15 示例 6 页面
在编写 Python 代码之前,我们需要确定目标数据的元素定位。在定位过程中,发现一个与以往不同的现象:有些数字在 HTML 代码中并不存在。例如口味的评分数据,其元素定位如图 6-16 所示。
图 6-16 评分数据中口味分数元素定位
根据页面显示内容,HTML 代码中应该是 8.7 才对,但实际上我们看到的却是:
1 |
<span class="item">口味:<d class="vhkjj4"></d>.7</span> |
HTML 代码中有数字 7 和小数点,但没有 8 这个数字,似乎数字 8 的位置被 d 标签占据。而商家电话号码处的显示就更奇怪了,一个数字都没有。商家电话对应的 HTML 代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 |
<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 标签的数量和数字的数量进行对比,发现它们的数量是相同的,也就是说一对 d 标签代表一个数字。
每一对 d 标签都有 class 属性,有些 class 属性值是相同的,有些则不同。我们再将 class 属性值与数字进行对比,看一看能否找到规律,如图 6-17 所示。
图 6-17 class 属性值和数字的对比
从图 6-17 中可以看出,class 属性值和数字是一一对应的,如属性值 vhk08k 与数字 0 对应。根据这个线索,我们可以猜测每个数字都与一个属性值对应,对应关系如图 6-18 所示。
图 6-18 数字与属性值对应关系
浏览器在渲染页面的时候就会按照这个对应关系进行映射,所以页面中显示的是数字,而我们在 HTML 代码中看到的则是这些 class 属性值。浏览器在渲染时将 HTML 中的 d 标签与数字按照此关系进行映射,并将映射结果呈现在页面中。映射逻辑如图 6-19 所示。
图 6-19 映射逻辑
我们的爬虫代码可以按照同样的逻辑实现映射功能,在解析 HTML 代码时将 d 标签的 class 属性值取出来,然后进行映射即可得到页面中显示的数字。如何在爬虫代码中实现映射关系呢?实际上网页中使用的是“属性名数字”这种结构,Python 中内置的字典正好可以满足我们的需求。我们可以用 Python 代码测试一下,代码如下:
1 2 3 4 5 6 7 8 9 |
# 定义映射关系 mappings = {'vhk08k': 0, 'vhk6zl': 1, 'vhk9or': 2, 'vhkfln': 3, 'vhkbvu': 4, 'vhk84t |