记大众点评反爬虫解析
个人博客地址:https://www.de009.top/volkswagen-points-to-comment-on-the-anti-reptile-resolution.html首先声明:博客内容禁止用于商业用途,仅做学习交流。如果侵犯了您的利益和权益,请联系我,我将删除该博客。
最近用大众点评网页版时,发现大众点评上所有的店家的信息都是无法复制的(后知后觉),老反爬虫了,十分好奇其原理,于是找了各种技术帖子,终于算是搞明白了,在此做一个笔记。
一、原理解析
当我们打开大众点评商店的页面时,我们是可以看到商店的地址与电话等信息的
但是若我们选中这些内容复制粘贴到txt中时,信息就会消失
查看html源码
那么首先肯定是去查看html页面源码中的内容了
首先
这里我们可以看到在地址“北”字所在的位置由一个bb标签所代替了
而电话中显示数字的位置则是一个cc标签
从上图中,我们不难看出,所有无法复制的字符和数字都被固定格式的标签代替了
<bb class=".*?"></bb> #地址栏缺失部分
<cc class=".*?"></cc> #电话栏缺失部分
接下来我们开始仔细看bb
和cc
标签的各种细节
1.CSS文件
在查看bb和cc的属性时,我们可以发现每一个bb
和cc
标签都有一个css的background
属性。并且通过class选择器指定到每一行bb
和cc
标签,也就是说每一个bb
和cc
中background
的值都是不同的。
再看background
的值-98.0px -196.0px
看起来像是一个二维的坐标,来指定页面上的一个点。
通过该属性右上角的css文件名,我们可以在html源码的head中找到该指向该css的url
在打开该css的url后,我们可以看到大量的与class相对应的二维坐标值
在该页中我们也能够找到之前在控制台中看到的对应着class="jp14j"
那组坐标
2.svg文件
再接着向下看,我们能够看到一长串css属性,bb[class^="jp"]
选择了所有class
的值以jp
开头的bb标签,而我们之前看到的class="jp14j"
的bb标签也正好符合该要求
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
属性看起来十分的可疑,
该属性的值为:url(//s3plus.meituan.net/v1/mss_0a06a471f9514fc79c981b5466f56b91/svgtextcss/5bab0148282110365d7ef47a72d7e6f5.svg)
该值为一个url,指向一个svg文件
在//前加上http:访问后我们能看到如下页面
页面源码
在上图该页面的源码中,我们可以看到源码分为三个大块:
在<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
取绝对值,也就是196
与d="M0 (.*?) H600"
括号内的数值对比,在大于y的值中取与之最接近的那一行,在该例子中,211
大于196
且最接近,而211
所对应的id
为7
,对应下方的第7
行
在第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, '春')]
无论是地址还是电话,思路皆相同。
附加:可能不同的svg文件
在多次查看验证svg文件时,发现有时svg文件会出现不同的写法,具体如图:
在该svg中,不再有<defs>
和<textPath>
的标签,取而代之的是单个的<text>
标签和其中y
属性值。
但是其实其核心思路并没有变,甚至更简单了,我们只需将y的绝对值与<text>
标签中y
属性值对比,取大于y且与其最接近的一行,再用相同思路利用x来找到对应的字符即可。
总结
1.以上所有解析是皆可用python实现,读者可以选择自己尝试,