栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

某点评网越来越难爬?你需要Python和一点想象力!

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

某点评网越来越难爬?你需要Python和一点想象力!

摘要:本文讲述了爬取某点评网的一点小技巧
关键词:Python 爬虫 大众点评 反爬
本文为闫树爽&大鹏共同完成

写一段python代码,就能让程序自动进行网站访问、解析数据并保存下来,再进行下一步分析,这是一项很酷的技能。

不过网站也不希望自己被爬虫爬走数据,所以一般来说,都有自己的反爬方式。比如判断用户IP在短时间内是否频繁访问对应网站,比如通过动态页面增加爬取的难度,达到反爬虫的目的等等。

而某点评网的反爬可以说是很有创意的一种了,它使用svg和乱码来防止被爬。难爬不说,就算拿到数据,使用者也不知道是什么意思。

今天我们就来看看,如何绕过某点评的反爬措施,获取数据,完成老板给的任务,升职加薪……

1.观察网站

我们以某商家的电话号码为例,先看看某点评的反爬措施。

在浏览器里按F12打开开发者工具,并使用select工具选中电话,可以看到电话数字除了1以外都是乱码。

通过仔细观察发现该电话最后两个数字都是9,我们对应看到d标签里面的两个class是相同。

这说明该class是用来代表某个数字的。我们先把这几个class和这个数字1弄下来,上Xpath!上正则!

def get_code(url):

    response = requests.get('url',headers=headers).text

    item = etree.HTML(response)
    item = item.xpath('//p[@class="expand-info tel"]')[0]
    item=etree.tostring(item).decode('utf-8')
    item = re.sub('|(d+)',item,re.S)
    phone_list=[]
    for i in items:
 phone_list.append(i[0] if i[0]!='' else i[1])
    return phone_list

XPath 是一门在 XML 文档中查找信息的语言,可用于HTML。XPath 可在HTML文档中对元素和属性进行遍历。
正则表达式(Regular expression,在代码中常简写为regex、regexp或re),是计算机科学的一个概念。正则表达式通常被用来检索、替换那些符合某个模式(规则)的文本。关于python正则表达式的更多资料,大家可以查看文末的资料福利。

通过正则表达式和xpath我们拿到了一个带有数字和乱码的列表,代表的是商家电话号码。这里把原有的数字放在这里是为了保留原来的顺序不变,以便我们后面处理:

再仔细观察,点击每个代表数字的d标签后background里面的两个数字有变化,说明这里就是控制着数字变化的地方。

我们继续找,上方还有个background-image,里面有一个以svg结尾的url。直接打开发现,里面不正是我们想要的数字吗?开搞开搞~

2.获取css数据

同样按F12打开开发者工具,我们发现这个svg里面包含了4个text标签,里面有一个x和一个y,里面包含了一堆数字。除此之外,里面还有一段数字文本。

经过我严密的推理,这些数字文本应该就是我们需要找的最终目标了,这里面的x和y应该和上面的background有些关系,我们先把这几个数字拿到手。

首先获取css

def get_css(url):

    response = requests.get(url,headers=headers).text

    html = etree.HTML(response)
    css_url = html.xpath('//link[@rel="stylesheet"]/@href')
    return 'http:'+css_url[1]

用requests获取到css文本,然后print看一下,搜索下上面的class,确保我们找到的css文本正确无误。

继续用正则表达式根据传入的class定位到backgrount后面的两个数字

def get_css(url):

    response = requests.get(url,headers=headers).text

    html = etree.HTML(response)
    css_url = html.xpath('//link[@rel="stylesheet"]/@href')
    return 'http:'+css_url[1]
3.反爬原理

之后就是将text和电话号码对应起来了。经过我天(wu)才(shu)地(ci)尝试,电话号码配对方法是这样的:这是一个需要三次定位的密码,分别是y值定位、x值定位,x[index]值定位。

先说说y定位,还记得数字对应的background数字吗?将后面的数字绝对值(此处是122)加上文字height(此处是30)得到y定位(152)。

使用y定位(152)与前面svg页面里的text标签中的y值进行对比,y定位(152)与哪个y值离得最近就取那个分组。本案例中y定位(152)最靠近第四个text标签(y=‘145’),所以我们会从第四个分组寻找x定位。

x定位和y定位相似,取的数字是background里面的第一个数字绝对值(302)加上6,得到对应的x定位(308),和x定位数值相同的text里面的数字所在的位置(index)就是我们最后需要的数字(该案例是21)。

最后查看text标签里的数字(num),x定位的index位置上的数字就是我们要的数字(数字5)。
要实现上面的揭秘过程,先构建python函数。这里用到了numpy库,主要是处理起来比较方便。先xpath得到所有的y值,存储到array数组中。

def get_svg(svg_url,x_,y):

    response = requests.get(svg_url)

    html = etree.HTML(response.content)
    y_list = html.xpath('//text/@y')//获取到所有的y

    y_list = np.array(y_list)
    y_list=y_list.astype(np.int64)
    y_index = np.abs(y_list-y).argsort()[0]
    y_ = y_list[y_index]
    x=html.xpath('//text[@y="{y}"]/@x'.format(y=y_))
    num = html.xpath('//text[@y="{y}"]/text()'.format(y=y_))

    dict_x = dict(zip(x[0].split(),list(num[0])))
    return dict_x[str(x_)]

这里传入的y值是我们上面background得到的第二个数字,和array数组做个差值,用abs取绝对值,排序,取到差值最小的index,再根据这个Index获取到我们需要的y值。

之后得到我们对应的那组数,然后继续xpath,得到了num和x,将他们组装成一个字典,获取到正确的数字。遍历一下codes, 就可以得到最终需要的电话号码。

自此,我们破解了某点评网的字体反爬。本文用电话号码举例,其实抓取网站中的的口味,环境,服务等字段也是同样的方法。

作为技术,爬虫是合法合理的。诸如谷歌百度这样搜索引擎,也都利用爬虫技术进行全网扫阅,供用户筛选信息,做成产品。网站和爬虫之间,有一个类似道德规范的robots协议。说他类似道德规范,是因为这个协议并没有被立法,这也是网站为什么要设置反爬措施的原因。但作为数据分析师,爬取数据前应该想清楚哪些数据是必须的,不做多余动作,节省自己的时间,也节约网站资源。


福利时间

最后分享一点学习福利,我曾经做过一系列免费干货直播,也收集了一些资料,可以加助教小姐姐微信获取:

Part.1:系列直播涵盖以下方面:

1、数据分析行业形势
2、数据爬虫
3、python和算法
4、数据可视化
5、综合数据案例

Part.2: 【6G】数据分析综合学习资料


最重要的是,这些都是免费!免费!免费的!想学习Python的你,还在等什么!快快扫码添加课程小姐姐免费获取资料吧~

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/224599.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号