every blog every motto: Let’s be loyal to our ideals, let’s face reality-Chegwara

前言:
知难不难!
折腾了几天爬取大众点评的数据,在这顺便总结一下,重新整理一下思路。希望能帮助那个此时正在奋斗的你,你并不是一个人在战斗!
环境: python3.7 + ubuntu16.04(window也可以)
库: requests、正则表达式等
所需知识: python基础语法、requests、正则
状态: 本博文已基本完善,不出意外,后续不再更新 。2019.4.14.15:28

正文

一、文字阐述

现在大众点评采取了css反爬机制,爬取难度越来越大。目前只有店铺名是明文(如图一) ·---------------------------------------------------------------图一
像详细地址等信息都是加密(如图二),如果直接爬取,我们会发现爬取的信息都是缺胳膊断腿的。比如,“广”字,它是被span标签所替代了。当我们点击span的标签会发现一个url(如图二3)以及一个坐标(如图二4)这都是我们解密的关键!
---------------------------------------------------------图二
戏说解密 :我们知道一个网页是由无数个“块”组成,那大众点评又是如何隐藏信息的呢?目前大众点评是采取css反爬机制。比如一面“墙”(网页)挖了一个小洞(洞的大小刚好能显示一个字),在“墙”的后面有一张纸(上面有一些字),通过坐标(图二4)来移动纸张,使得想要的“字”出现在洞口,从而能在网页上能正常显示。(如图三)
------------------------------------------------------------图三
通过“戏说”,我们知道第一步应该获取“那张纸”(图二中的3,background-iamge),而background-image应该是css样式,保存在css中。我们打开网页源代码(谷歌浏览器,右击,倒数第二就是),如图四(注意是以.css结尾)
--------------------------------------------------------图四
点开css链接(如图五),我们发现有“4张纸”(4个svg_link,此处可按ctrl+F,输入background-image查看)
------------------------------------------------------------图五

二、代码

(为方便理解,实参和形参基本同名。此文仅展现详细地址提取,其余信息请查阅源码【结尾附】

0.主程序

def main():############################-------获取地址-----------#########################################url = 'http://www.dianping.com/beijing/ch10/g311p{}'.format(num)# 1.1 获取css样式文件html_origin, html_css = get_css_link(url)# 1.2 获取地址的前两个字母 地址的class=addr,传入addrfront_two_alp_addr = get_front_two_alp(html_origin, class_name='addr')# 1.3 获取地址对应的svg链接addr_svg_link = get_svg_link(html_css, front_two_alp_addr)# 2. 获取html_css有关地址的(background,x,y)font_css = get_font_css(html_css, front_two_alp_addr)# 3.2 获取css样式对应的地址字典文件  //第二种加密方法-new-无M0font_list = get_font_dict_by_offset_new(addr_svg_link, font_css)# 4. 获取地址  /** 这里有一个地址字典后续要用addr_font = get_result_font(html_origin, font_list, head_span_class_name='addr')

1.提取css_link(css链接)

# 1.1 获得css样式的链接
def get_css_link(url):''' 获取css链接 '''print('--->start-1.1-get_css_link--------------------------')# 获取网页源码html_origin = requests.get(url, headers=headers).text# 正则表达式匹配css链接css_link = re.search('<link rel="stylesheet" type="text/css" href="(//s3plus.meituan.net.*?.css)">', html_origin,re.S)# print(css_link.group(1))css_link = 'http:' + css_link.group(1)html_css = requests.get(css_link, headers=headers).textprint('==================================1.1>>>over!')# 返回网页源码和css_linkreturn html_origin, html_css

2.提取svg_link

(即background_image后面的链接)
注:因为不只详细地址采用了这种方式,所以才会如前所述有4个svg_link.所以我们要先提取详细地址的部分class_name(图二5)(有时候是前三个字母一样,有时候是前两个字母一样),通过这前几个字母不仅能提取对应的svg_link,还能筛选想要的css(图五,此处接下第三步)

2.1提取前面字母

# 1.2 获取前两个字母
def get_front_two_alp(html_origin, class_name):'''获取地址的隐藏字体的class_name 前三个字母'''print('--->start-1.2-get_front_two_alp----------------')# 通过一级span的class_name,取出其子标签的class_name前三个字母front_three_alp = re.search('<span class="' + class_name + '">.*?<span class="(\w\w).*?"></span>', html_origin,re.S)# print('打印地址的前两个字母')# print(front_alp_addr.group(1))print('==================================1.2>>>over!')# 返回地址的class_name的前三个字母return front_three_alp.group(1)

2.2提取svg_link

# 1.3 获取svg_link
def get_svg_link(html_css, front_two_alp_addr):# 获取的svg链接print('--->start-1.3-get_svg_link--------------------------')alp = front_two_alp_addr# print(alp)background_image_link = re.search(alp + '"]{.*?background-image: url\((//.*?svg)\)', html_css)# print(background_image_link.group(1))background_image_link = 'http:' + background_image_link.group(1)print('==================================1.3>>>over!')return background_image_link  # 地址对应此链接

3.筛选有关地址的css,(background,x,y)

# 2. 筛选有关地址的css,(background,x,y)
def get_font_css(html_css, front_alp_addr):'''获取html_css里面有关地址的(class_name,x,y)'''print('--->start-2-get_font_css--------------------------')font_css = re.findall('\.({0}\w\w\w)'.format(front_alp_addr) + '{background:-(\d+).0px -(\d+).0px;}', html_css,re.S)# print('addr_css')# print(font_css)print('==================================2>>>over!')return font_css

4.获得class_name 对应的文字

注:

  1. 文字有两种加密方式,数字又是另一种加密方式。(大众点评会在每天下午四点到晚上九点之间更换加密方式,并且每个加密的字,的class_name(图二5)也会变,有时候是前三个字母一样,有时候是前两个字母一样[如图二5])
  2. 简单说一下,每一个隐藏的字由一个span标签对应(注意这里是一一对应,类似函数的映射)而span标签又是由class_name唯一确定,这里寻找class_name:font的对应关系(为保证文章的完整性,解密详细步骤放在后面
# 3.2获得class_name 对应的文字  //第二种加密方法-new-无M0
def get_font_dict_by_offset_new(svg_link_num, food_kind_css):'''获取坐标偏移的文字字典'''print('--->start-3.2-get_addr_addr_dict_by_offset_new--------------')# print(addr_css)svg_html = requests.get(svg_link_num, headers=headers).text# print(svg_html)font_finded = {}y_list = re.findall('<text x=.*?y="(\d+)"', svg_html)# print('y_list:')# print(y_list)y_list_new = []for i in enumerate(y_list):y_list_new.append(i)# print('y_list_new')# print(y_list_new)# print(comment_css)if y_list:font_finded = re.findall('<text .*?>(.*?)<', svg_html)# print(font_finded)offset_x = []offset_y = []font_list = []for food_css_name_x_y in food_kind_css:for y in y_list:if int(food_css_name_x_y[2]) < int(y):offset_x = int((int(food_css_name_x_y[1]) / 12))# print('offset_x')# print(offset_x)for one_y in y_list_new:if int(one_y[1]) == int(y):offset_y = one_y[0]font_list.append((food_css_name_x_y[0], font_finded[offset_y][offset_x]))break# print(font_list)print('==================================3.2>>>over!')return font_list

5.提取地址

注:

  1. 替换span标签为文字
  2. 提取文字
# 4. 提取地址
def get_result_font(html_origin, font_list, head_span_class_name):print('--->start-4-get_addr--------------------------')# print(font_list)for font in font_list:html_origin = html_origin.replace('<span class="' + font[0] + '"></span>', font[1])# 替换成功提取地址result_font = re.findall('<span class="' + head_span_class_name + '">(.*?)</span>', html_origin, re.S)# print(result_font)print('==================================4>>>over!')return result_font

6.成果


-----------------------------------------------------------------------图六

三、解密

1.第一种加密方式,解密

(为便于书写,此处图片在上,文字在下)
-----------------------------------------------------------图七
我们以上文提到的“广”为例(,如(图二4)background:-468px,-184px,简写如(ywbsy,468,184)【即(class_name,x__,y__),加密规则如此,不要像素前面的负号】
1.通过y__和图七的y比较,当第一个y>y__时,所要确定的文字就在那一行(此处有点难理解)例:208>184 所以对应文字在最后一行(图七2)
2.x__/12(12是文字大小,即上文提到的“洞的大小”[图七1])例 :468/12=39,数最后一行,可定位到“广”(如图七)注意:从0开始数

2,第二种加密方式,解密


-------------------------------------------------------图八
解密开始:
1.通过y__和M0后面的数字比较,规则和上面的相同,从而确定id的值(图八2)再通过,id==href(id和href是一一对应的,比如你确定id = 20,那么就去href=20的那一行去找),从而确定文字所在行。
2.x__ / 12 的值确定偏移量。
注:目前的两种解密方式,分两个函数来写。加密规则一变调用另一个函数即可。

四、结束语

  1. 目前加密规则大同小异,有的时候是偏移量加一减一的区别(是否从0开始数)
  2. 数字加密规则:x__/12不是整数,可以通过向下取整(也可以通过向上取整),再寻找。
  3. 店铺的经纬度,尚不知如何直接提取,如若有大神知道,烦请告知一二,不甚感激。
  4. 加密规则有两种,class_name前面字母相同个数有两种。此代码有效期不超过24小时,可调用不同函数解决。
  5. 源码已做部分更新,和此博文有些许出入,详情请查阅源码。
  6. contact by email: gaofeng.anhui@gamil.com
  7. 源码: https://github.com/onceone/dazhongspider/tree/master

知识无价,如果帮助到你,不妨请喝一杯奶茶~~

参考文章:

[1] 崔庆才.Python3网络爬虫开发实战[M].北京:人民邮电出版社,2018.
[2] https://blog.csdn.net/weixin_42512684/article/details/86775357
[3] https://blog.csdn.net/sinat_32651363/article/details/85123876
[4] https://blog.csdn.net/Tilyp/article/details/88754591
[5] https://blog.csdn.net/Herishwater/article/details/89036554
[6] https://www.google.com/
[7] https://www.baidu.com/

反反爬虫之--爬取大众点评--店铺名称、详址、经纬度、评价人数、平均消费等信息相关推荐

  1. python爬虫实战---爬取大众点评评论

    python爬虫实战-爬取大众点评评论(加密字体) 1.首先打开一个店铺找到评论 很多人学习python,不知道从何学起. 很多人学习python,掌握了基本语法过后,不知道在哪里寻找案例上手. 很多 ...

  2. python爬虫爬取大众点评店铺简介信息

    python爬虫爬取大众点评店铺简介信息 写作目的: 爬取目标 大众点评的保护机制 应对方法 还存在的问题 写作目的: 今天帮朋友一个忙,要爬取一些大众点评上的数据.结果发现大众点评的防爬机制还挺多的 ...

  3. 大众点评 爬虫 java_用JAVA制作一个爬取商品信息的爬虫(爬取大众点评)

    很多企业要求利用爬虫去爬取商品信息,一般的开发模型如下: for i=1;i<=最大页号;i++ 列表页面url=商品列表页面url+?page=i(页号) 列表页面=爬取(列表页面url) 商 ...

  4. Python,requests爬虫,使用代理爬取大众点评(含爬取结果。。。在文末)

    由于在工作中,客户需要大众点评的行业数据,因此本人使用Python对大众点评网站进行了爬取,虽然在爬取之前就想好了可能会遇到的坑,但是没想要从坑中爬出来这么难.本次大众点评爬虫代码编写耗时一个月.也算 ...

  5. 为了部落 来自艾泽拉斯勇士的python爬虫学习心得 爬取大众点评上的各种美食数据并进行数据分析

    为了希尔瓦娜斯 第一个爬虫程序 csgo枪械数据 先上代码 基本思想 问题1 问题2 爬取大众点评 URL分析 第一个难题 生成csv文件以及pandas库 matplotlib.pyplot库 K- ...

  6. python爬虫大众点评_python爬虫——按城市及店铺面爬取大众点评分类

    题外话:因为最近遇到很多标签要对其进行分类,其中很多是店铺名,所以就想爬取大众点评的分类信息.因为不是专门做爬虫的,所以下面这段代码仅仅是可以实现要求,如何能避免网站的反爬机制这一点就无能无力了.另外 ...

  7. python爬取大众点评数据_python爬虫实例详细介绍之爬取大众点评的数据

    python 爬虫实例详细介绍之爬取大众点评的数据 一. Python作为一种语法简洁.面向对象的解释性语言,其便捷性.容易上手性受到众多程序员的青睐,基于python的包也越来越多,使得python ...

  8. 爬取大众点评数据的血泪史

    公司最近致力于实现餐饮行业的AI发展模式,领导希望采集一些餐饮数据来提供理论支持.所以没多少头发的我 ,被喊过来做数据收集. 想到餐饮数据的收集,第一反应是去爬取美团/大众点评的数据,对比了下美大众点 ...

  9. 爬取大众点评页面数据教程,图片文字如何爬取

    大众点评的商家地址和详细分类,居然是用svg图形展示的文字,哇,真是用心良苦,为了反爬,可谓是脑洞大开啊,图形文字.滑块验证码.封ip,全都用上了,真是让人头疼.不过正所谓道高一尺,魔高一丈,没有达不 ...

最新文章

  1. 海洋主题绘画_神奇宝贝:海洋生物的艺术世界绘画比赛获奖作品展来啦!
  2. oracle配置oracle Database Configuration Assistant失败是什么原因?
  3. (2)ARM Cortex-M3指令集
  4. CIKM 2020 | 知识库问答复杂问题的分层查询图生成方法
  5. PCL:PCL1.9.0更新
  6. 【Linux】 诊断工具-strace
  7. 《it创业疯魔史》读后有感
  8. Linux之Ubuntu安装搜狗输入法
  9. oracle manager 配置,Oracle Net Manager 基本配置
  10. ViewPager子类与父类滑动冲突的情况
  11. (2)WePHP 控制器与使用模板
  12. 商城管理系统(前台+后台+管理员+用户+html+jsp)
  13. 腾讯java笔试题_腾讯java笔试题
  14. 服务器默认用户名密码
  15. 网页|利用touch实现下拉刷新
  16. VMWare16上安装CentOS 7镜像
  17. 关于Excel被保护的工作表忘记密码的强制解除办法
  18. 在 100% 鲜活的时间,请让我遇见你
  19. Task2 数据分析 (1)
  20. 计算不规则四边形(多边形)的面积

热门文章

  1. linux安装音乐软件教程,Linux上好用的五款音乐播放器
  2. 体外(无细胞)蛋白表达试剂盒-原核蛋白表达系统(基于大肠杆菌内源的转录和翻译机制)
  3. MySQL 根据指定某一天的时间查询数据
  4. 被勒索后的72 小时“生死时速”
  5. 嵌入式工程师面试题集汇总
  6. 狗急跳墙型产品经理..学习...
  7. 企业级产品需要解决客户问题,带来价值,唯技术论是不可取的
  8. linux如何判断网线插入_Linux自动判断是否插入网线的几种方法
  9. 微信小程序订阅消息点了 “总保持以上选择、全部拒绝,不在询问” 无法再次弹出
  10. “四大名著“————计算机网络