【Python3爬虫】大众点评爬虫(破解CSS反爬)
本次爬虫的爬取目标是大众点评上的一些店铺的店铺名称、推荐菜和评分信息。
一、页面分析
进入大众点评,然后选择美食(http://www.dianping.com/wuhan/ch10),可以看到一页有15家店铺,而除了店铺的名称,还能看到店铺的地址、推荐菜、评分等信息,看起来都没什么问题。

打开开发者工具,然后选择查看一下评分,就发现事情没那么简单了(如下图)。这些评分的数字去哪儿了呢?

其实这些数字是SVG矢量图,SVG矢量图是基于可扩展标记语言,用于描述二维矢量图形的一种图形格式,通过使用不同的偏移量就能显示不同的字符,这样就能很巧妙地隐藏信息了,如果我们用xpath去解析网页得到的就是一个个""。这次爬虫的难点就在于如何得到这些评分的信息,既然我们能够知道它是怎么反爬的,那我们是不是就能想办法实现反反爬呢?先说下破解思路吧:首先要解析网页,找到这个网页使用的SVG矢量图,拿到这个矢量图后,如果我们能得到每个数字对应的偏移量,那就能将这些偏移量转化成图片中的数字了。
二、破解步骤
首先查看网页源码,既然使用的是SVG矢量图,那我们搜索一下svg会不会有惊喜呢?果然有惊喜:

把这个链接复制一下,然后打开这个链接,会看到有很多的class名称和background,这么多的数据,怎么知道有没有我们想要的东西呢?这时候搜索一下unbq2:

可以看到unbq2这个class对应的background为(-199.0px,-109.0px),但是我们还是没有办法得到具体的数字啊,怎么办呢?
我们再搜索一下svg会有什么结果呢?这一步会得到几个以.svg结尾的链接,将这些链接提取出来:
span[class^="ma"]{background-image: url(//s3plus.meituan.net/v1/mss_0a06a471f9514fc79c981b5466f56b91/svgtextcss/9e045e6574fb7ae10b5aae4ae4a0c444.svg);span[class^="yj"]{background-image: url(//s3plus.meituan.net/v1/mss_0a06a471f9514fc79c981b5466f56b91/svgtextcss/39510b070120e6a5b7c8754ab729ee2e.svg);span[class^="dz"]{background-image: url(//s3plus.meituan.net/v1/mss_0a06a471f9514fc79c981b5466f56b91/svgtextcss/8eecf780b3c9ecefd5ad508502dd80a5.svg);span[class^="un"]{background-image: url(//s3plus.meituan.net/v1/mss_0a06a471f9514fc79c981b5466f56b91/svgtextcss/39ecd4a57969825db02c38a01f4f34c6.svg);
可以看到以"un"开头的class使用的背景图片的链接就是//s3plus.meituan.net/v1/mss_0a06a471f9514fc79c981b5466f56b91/svgtextcss/39ecd4a57969825db02c38a01f4f34c6.svg

这就是我们要找的SVG矢量图了,现在的问题就在于如何将偏移量转化成对应的数字呢?首先把这些数字提取出来:
99851465728255648017534661485297040380627087820023
03763928255311814779807306445209731282368541175419
06266544999197136339
然后打开开发者工具,可以发现每个数字都有对应着一组x和y的值:

在前面的分析中我们知道数字6对应的偏移量是(-199.0px,-109.0px),然后我们也可以分析一下别的数字对应的偏移量,然后通过这些分析可以知道y方向上的偏移量只是为了确定这个class对应的数字在哪一行,而x方向的偏移量需要进行一下处理,具体方法为:
(x方向上的偏移量+7)/(-12)
比如(-199+7)/(-12)=16,这个16就表示对应的数字索引为16(第一个数字索引为0),然后y方向的偏移量对应的行数为3,最后从上面的数字中寻找第3行第17个数字--正好为6,也就是说unbq2这个class对应的数字就是6,这样我们就已经成功实现了反反爬。
三、爬取步骤
由于大众点评会对我们的UserAgent和Cookie进行检查,所以在爬取的时候要带上Cookie,而且如果一直用一个UserAgent也会被识别出来,所以得采用不同的UserAgent。这里我要分析一个第三方模块:fake_useragent,没有安装这个模块的可以使用pip命令进行安装。我们通过使用这个模块就能得到随机的UserAgent了,使用方法如下:
from fake_useragent import UserAgent ua = UserAgent()
for i in range():
print(ua.random)
运行结果如下:

店铺名称和推荐菜的爬取相对简单,这里就不赘述了,主要说一下如何爬取店铺的评分信息。
在我们得到网页的源码之后,需要先把css文件的url提取出来:
# 提取css文件的url
css_url = "http:" + re.search('(//.+svgtextcss.+\.css)', html).group()
然后将以"un"开头的class名称和对应的偏移量全部提取出来,以供后面使用:
css_res = requests.get(css_url)
# 这一步得到的列表内容为css中class的名字及其对应的偏移量
css_list = re.findall('(un\w+){background:(.+)px (.+)px;', '\n'.join(css_res.text.split('}')))
这里还要对得到的数据进行一下处理,因为y方向上的偏移量并不参与计算,最终得到的y_dict中的键是y方向上的偏移量,值是y方向上的偏移量对应的行数:
# 过滤掉匹配错误的内容,并对y方向上的偏移量初步处理
css_list = [[i[0], i[1], abs(float(i[2]))] for i in css_list if len(i[0]) == 5]
# y_list表示在y方向上的偏移量,完成排序和去重
y_list = [i[2] for i in css_list]
y_list = sorted(list(set(y_list)))
# 生成一个字典
y_dict = {y_list[i]: i for i in range(len(y_list))}
然后我们要提取以”un“开头的class所对应svg图片的url,并访问这个url,将图片中的数字都提取出来:
# 提取svg图片的url
svg_url = "http:" + re.findall('class\^="un".+(//.+svgtextcss.+\.svg)', '\n'.join(css_res.text.split('}')))[0]
svg_res = requests.get(svg_url)
# 得到svg图片中的所有数字
digits_list = re.findall('>(\d+)<', svg_res.text)
进行到这一步,我们就已经得到了所有以un开头的class对应的偏移量和所有的数字了,然后我们就可以利用前面的计算方法将这些偏移量转变成对应的数字了,也就能得到每个店铺的评分信息了。
最终运行结果如下:

完整代码已上传到GitHub!
【Python3爬虫】大众点评爬虫(破解CSS反爬)的更多相关文章
- Python爬虫反反爬:CSS反爬加密彻底破解!
刚开始搞爬虫的时候听到有人说爬虫是一场攻坚战,听的时候也没感觉到特别,但是经过了一段时间的练习之后,深以为然,每个网站不一样,每次爬取都是重新开始,所以,爬之前谁都不敢说会有什么结果. 前两天,应几个 ...
- 爬虫--反爬--css反爬---大众点评爬虫
大众点评爬虫分析,,大众点评 的爬虫价格利用css的矢量图偏移,进行加密 只要拦截了css 解析以后再写即可 # -*- coding: utf- -*- """ Cre ...
- Python爬虫实例:爬取猫眼电影——破解字体反爬
字体反爬 字体反爬也就是自定义字体反爬,通过调用自定义的字体文件来渲染网页中的文字,而网页中的文字不再是文字,而是相应的字体编码,通过复制或者简单的采集是无法采集到编码后的文字内容的. 现在貌似不少网 ...
- Python爬虫入门教程 63-100 Python字体反爬之一,没办法,这个必须写,反爬第3篇
背景交代 在反爬圈子的一个大类,涉及的网站其实蛮多的,目前比较常被爬虫coder欺负的网站,猫眼影视,汽车之家,大众点评,58同城,天眼查......还是蛮多的,技术高手千千万,总有五花八门的反爬技术 ...
- python爬虫的一个常见简单js反爬
python爬虫的一个常见简单js反爬 我们在写爬虫是遇到最多的应该就是js反爬了,今天分享一个比较常见的js反爬,这个我已经在多个网站上见到过了. 我把js反爬分为参数由js加密生成和js生成coo ...
- 【Python3爬虫】猫眼电影爬虫(破解字符集反爬)
一.页面分析 首先打开猫眼电影,然后点击一个正在热播的电影(比如:毒液).打开开发者工具,点击左上角的箭头,然后用鼠标点击网页上的票价,可以看到源码中显示的不是数字,而是某些根本看不懂的字符,这是因为 ...
- Python爬虫入门教程 65-100 爬虫与反爬虫的修罗场,点评网站,字体反爬之三
爬虫与反爬虫的修罗场 哪种平台最吸引爬虫爱好者,当然是社区类的,那里容易产生原生态,高质量的数据啊, 你看微博,知乎,豆瓣爬的不亦乐乎. 评论也是产生内容的好地方 生活类点评网站 旅游类点评网站 音乐 ...
- Node.js大众点评爬虫
大众点评上有很多美食餐馆的信息,正好可以拿来练练手Node.js. 1. API分析 大众点评开放了查询商家信息的API,这里给出了城市与cityid之间的对应关系,链接http://m.api.di ...
- 《C# 爬虫 破境之道》:第二境 爬虫应用 — 第六节:反爬策略研究
之前的章节也略有提及反爬策略,本节,我们就来系统的对反爬.反反爬的种种,做一个了结. 从防盗链说起: 自从论坛兴起的时候,网上就有很多人会在论坛里发布一些很棒的文章,与当下流行的“点赞”“分享”一样, ...
随机推荐
- java 中 一个int类型的num,num&1
n&1 把n与1按位与,因为1除了最低位,其他位都为0,所以按位与结果取决于n最后一位,如果n最后一位是1,则结果为1.反之结果为0.(n&1)==1: 判断n最后一位是不是1(可能用 ...
- 求第n个丑数
参考http://www.cppblog.com/zenliang/articles/131094.html 什么是因子:因子*因子=乘积数如果一个数是丑数,那么这个数是2,3,5的乘积的结果.比如: ...
- 从一个例子了解window.onload、$(function(){})、$(window).load(function(){})的加载顺序
最近遇到一个轮播需求: 1. ajax请求服务器,返回json,判断json数据里每一项中isFix属性是0还是1,0表示不轮播,1表示需要轮播. 2. 当isFix属性为0的时候,表示该图片不轮播, ...
- LuoguP4234_最小差值生成树_LCT
LuoguP4234_最小差值生成树_LCT 题意: 给出一个无向图,求最大的边权减最小的边权最小的一棵生成树. 分析: 可以把边权从大到小排序,然后类似魔法森林那样插入. 如果两点不连通,直接连上, ...
- javascript的键盘事件大全
javascript的键盘事件大全 ------------------------------------------------------------------- 使用event对象的keyC ...
- QTimer在QThread环境中失效的问题
QTimer在非QThread的环境下能正常工作.但在QThread环境下,需要做一些改动才能正常工作. 创建Qt的线程有两种方式: 1. 子例化QThread 可以在虚函数run中启动定时器,大致的 ...
- 基于Orangpi Zero和Linux ALSA实现WIFI无线音箱(一)
作品已经完成,先上源码: https://files.cnblogs.com/files/qzrzq1/WIFISpeaker.zip 全文包含三篇,这是第一篇,作为前言和概述. 第二篇:基于Oran ...
- 解决:git push error: failed to push some refs to
出现错误的原因是github中的README.md文件不在本地代码目录中. 也就是说我们需要先将远程代码库中的任何文件先pull到本地代码库中,才能push新的代码到github代码库中. 使用如下命 ...
- ssm上传图片
ssm上传图片 1 需求 添加客户时上传图片和客户修改信息是上传图片. 2 思路 首先,数据库创建pic字段,类型为varchar,通过逆向工程重新生成mapper接口和xml文件 ...
- .NET Core IdentityServer4实战 第二章-OpenID Connect添加用户认证
内容:本文带大家使用IdentityServer4进行使用OpenID Connect添加用户认证 作者:zara(张子浩) 欢迎分享,但需在文章鲜明处留下原文地址. 在这一篇文章中我们希望使用Ope ...