记大众点评反爬虫解析

个人博客地址:https://www.de009.top/volkswagen-points-to-comment-on-the-anti-reptile-resolution.html首先声明:博客内容禁止用于商业用途,仅做学习交流。如果侵犯了您的利益和权益,请联系我,我将删除该博客。
最近用大众点评网页版时,发现大众点评上所有的店家的信息都是无法复制的(后知后觉),老反爬虫了,十分好奇其原理,于是找了各种技术帖子,终于算是搞明白了,在此做一个笔记。

一、原理解析

Java 大众点评 大众点评玩法总结_python


当我们打开大众点评商店的页面时,我们是可以看到商店的地址与电话等信息的

但是若我们选中这些内容复制粘贴到txt中时,信息就会消失

Java 大众点评 大众点评玩法总结_c标签_02

查看html源码

那么首先肯定是去查看html页面源码中的内容了
首先
这里我们可以看到在地址“北”字所在的位置由一个bb标签所代替了

Java 大众点评 大众点评玩法总结_f5_03


而电话中显示数字的位置则是一个cc标签

Java 大众点评 大众点评玩法总结_python_04

从上图中,我们不难看出,所有无法复制的字符和数字都被固定格式的标签代替了

<bb class=".*?"></bb> #地址栏缺失部分
<cc class=".*?"></cc> #电话栏缺失部分

接下来我们开始仔细看bbcc标签的各种细节

1.CSS文件

在查看bb和cc的属性时,我们可以发现每一个bbcc标签都有一个css的background属性。并且通过class选择器指定到每一行bbcc标签,也就是说每一个bbccbackground的值都是不同的。

再看background的值-98.0px -196.0px看起来像是一个二维的坐标,来指定页面上的一个点。

Java 大众点评 大众点评玩法总结_css_05


Java 大众点评 大众点评玩法总结_c标签_06


通过该属性右上角的css文件名,我们可以在html源码的head中找到该指向该css的url

Java 大众点评 大众点评玩法总结_f5_07


在打开该css的url后,我们可以看到大量的与class相对应的二维坐标值

Java 大众点评 大众点评玩法总结_python_08


在该页中我们也能够找到之前在控制台中看到的对应着class="jp14j"那组坐标

Java 大众点评 大众点评玩法总结_f5_09

2.svg文件

再接着向下看,我们能够看到一长串css属性,bb[class^="jp"]选择了所有class的值以jp开头的bb标签,而我们之前看到的class="jp14j"的bb标签也正好符合该要求

Java 大众点评 大众点评玩法总结_c标签_10

bb[class^="jp"]{width: 14px;height: 22px;margin-top: -1px;background-image: url(//s3plus.meituan.net/v1/mss_0a06a471f9514fc79c981b5466f56b91/svgtextcss/5bab0148282110365d7ef47a72d7e6f5.svg);background-repeat: no-repeat;display: inline-block;vertical-align: middle;}

在浏览器的控制台中我们能够更加清晰地看到这些css属性

而其中这个background-image属性看起来十分的可疑,

Java 大众点评 大众点评玩法总结_css_11

该属性的值为:url(//s3plus.meituan.net/v1/mss_0a06a471f9514fc79c981b5466f56b91/svgtextcss/5bab0148282110365d7ef47a72d7e6f5.svg) 该值为一个url,指向一个svg文件

在//前加上http:访问后我们能看到如下页面

Java 大众点评 大众点评玩法总结_python_12


页面源码

Java 大众点评 大众点评玩法总结_css_13


在上图该页面的源码中,我们可以看到源码分为三个大块:

<defs>部分中每个path中id属性的值在递增,而d="M0 (.*?) H600"括号内的数值也在变化。

<text>部分中,xlink:href = '#num' 为 css 选择器,绑定了 <defs>/<path> 中的 id,而<textPath>的内容为一长串汉字。

3.整合线索

还记得之前我们在bb和cc标签中都找到过一对二维坐标值吗,在次我们以jp14j{background: -98.0px -196.0px;}为例,jp14j{background: -98.0px -196.0px;}标签在页面中对应的文字为 这里我们将其看作x:-98.0px y:-196.0px

首先我们将y取绝对值,也就是196d="M0 (.*?) H600"括号内的数值对比,在大于y的值中取与之最接近的那一行,在该例子中,211大于196且最接近,而211所对应的id7,对应下方的第7

Java 大众点评 大众点评玩法总结_c标签_14


在第7行中,有以下汉字

山乌鞍门绵教郑北青衡农河武定春

我们再取x的绝对值/字体大小即可算出x所对应的汉字是这行的第几个

98/14(字体大小为14px)=7

即我们例子中jp14j{background: -98.0px -196.0px;}标签所隐藏的字符就在这svg文件中的第7行,第7+1(应因为第一个字符的坐标为0)=8个字符,就下表来看,即字,与我们开头在页面上看到的字符一致,解析完成。

[(0, '山'), (1, '乌), (2, '鞍'), (3, '门'), (4, '绵'), (5, '教'), (6, '郑‘), (7, '北'), (8, '青'), (9, 衡'), (10, '农'), (11, '河'), (12, '武'), (13, '定'), (14, '春')]

Java 大众点评 大众点评玩法总结_css_15


无论是地址还是电话,思路皆相同。

附加:可能不同的svg文件

在多次查看验证svg文件时,发现有时svg文件会出现不同的写法,具体如图:

Java 大众点评 大众点评玩法总结_f5_16


在该svg中,不再有<defs><textPath>的标签,取而代之的是单个的<text>标签和其中y属性值。

但是其实其核心思路并没有变,甚至更简单了,我们只需将y的绝对值与<text>标签中y属性值对比,取大于y且与其最接近的一行,再用相同思路利用x来找到对应的字符即可。

总结

1.以上所有解析是皆可用python实现,读者可以选择自己尝试,