刚开始搞爬虫的时候听到有人说爬虫是一场攻坚战,听的时候也没感觉到特别,但是经过了一段时间的练习之后,深以为然,每个网站不一样,每次爬取都是重新开始,所以,爬之前谁都不敢说会有什么结果。
前两天,应几个小朋友的邀请,动心思玩了一下大众点评的数据爬虫,早就听说大众点评的反爬方式不一般,貌似是难倒了一片英雄好汉,当然也成就了网上的一众文章,专门讲解如何爬取大众点评的数据,笔者一边阅读这些文章寻找大众点评的破解思路,一边为大众点评的程序员小哥哥们鸣不平,辛辛苦苦写好的加密方式,你们这些爬虫写手们这是闹哪样?破解也就算了,还发到网上去,还发这么多~
笔者在阅读完这些文章之后,自信心瞬间爆棚,有如此多的老师,还有爬不了的网站,于是,笔者信誓旦旦的开始了爬大众点评之旅,结果,一上手就被收拾了,各个大佬们给出的爬虫方案中竟然有手动构建对照表的过程,拜托,如果我想手动,还要爬虫做什么?别说手动,半自动都不行。
大家看到这里或许头上有些雾水了,什么手动?什么半自动?还对照表?大佬,你这是什么梗?再不解释一些我就要弃剧了,葛优都拉不回来~
 
大家先不要着急,静一静,对照表后面会讲,这里只需要知道我遇到困难了,就可以了,不过咨询了几个大佬之后,好在解决了,革命的路上虽有羁绊,终归还是有同志的
好,现在开始入正题,点评的程序员哥哥请不要寄刀片:
 
 
1 基础环节
大众点评的数据爬虫开始还是很正常的,各个题目、菜单基本上都可以搞下来:
代码如下:
#!/usr/bin/env python # _*_ UTF-8 _*_ import requests from lxml import etree header = {"Accept":"application/json, text/javascript", "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8", "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36", "Cookie":"cy=1; cye=shanghai; _lxsdk_cuid=16ca41d3344c8-050eb4ac8f1741-4d045769-1fa400-16ca41d3345c8; _lxsdk=16ca41d3344c8-050eb4ac8f1741-4d045769-1fa400-16ca41d3345c8; _hc.v=38ae2e43-608f-1198-11ff-38a36dc160a4.1566121473; _lxsdk_s=16ce7f63e0d-91a-867-5a%7C%7C20; s_ViewType=10" } url = 'http://www.dianping.com/beijing/ch10/g34060o2' response = requests.get(url, headers=header) data = etree.HTML(response.text) title = data.xpath('//*[@id="shop-all-list"]/ul/li[1]/div[2]/div[1]/a/@title') print(title)
爬取的结果为:
按照常规的套路,爬虫可以说是写成了。但是,现在的网站大多使用了反爬,一方面担心自己的服务器会被爬虫搞的超负荷,另一方面也为了保护自己的数据不被其他人获取。
大众点评就是众多带反爬的网站中的佼佼者,使用了比较高级的反爬手法,他们把页面上的关键数字隐藏了起来,增加了爬虫难度,不信~你看:
2 CSS加密
我们用如下字段爬取商店的评论数:
data = etree.HTML(response.text) title = data.xpath('//*[@id="shop-all-list"]/ul/li[1]/div[2]/div[2]/a[1]/b/svgmtsi[1]/text()') print(title)
结果得到的却是如下字段:
一看傻了,这是什么鬼?
我们紧接着审查了网站数据,看到的内容却是:
 
这是什么鬼?评论数呢?
查看了网站的源代码:
发现原来显示点评数的字段显示成了:
这是为什么呢?
好在网上的大神们给出了解答,这就是CSS加密。
接下来我们就介绍如何破解CSS加密:
我们把源代码上加密的部分取下来观察一下:
<svgmtsi></svgmtsi>
我们发现了网上一直在讨论的svgmtsi标签,这个标签是矢量图的标签,基本上意思就是显示在这里的文字是一个矢量图,解析这个矢量图需要到另外一个地方找一个对照表,通过对照表将编码内容翻译成人类可以识别的数字。
那么,对照表在哪里呢?
我们先记录下标签中的class值:shopNum(为什么记录,先不要着急,后面会讲到),然后在源代码中查找svg,我们发现了如下内容:
大宝藏被挖掘了。
这好像是个链接,我们点击一下,发现页面跳转到了一个全新的水月洞天:
这真是个伟大的发现,他预示着我们的爬虫找到了门路,我们在这个页面上查找刚才class中的值shopNum,然后,我们看到了如下内容:
.shopNum{font-family: 'PingFangSC-Regular-shopNum';}@font-face{font-family:
"PingFangSC-Regular-reviewTag";
在这段代码中距离shopNum最近的地方,我们找到一个woff文件。
你没有猜错,这个woff文件就是我们的对照表。
同样的思路,这是一个网址,我们可以把他下载下来,把这个网址复制到浏览器的地址栏中,点回车,会跳出如下快乐的界面。
 
 
下载完成后,我们在浏览器中打开woff的翻译工具:
我们把前面的&#x去掉并替换成uni,后面的;去掉,得到字段为:unif784。
秘密揭晓了:
是不是很眼熟?
是不是很惊喜?
是不是很意外?
恭喜你,第一步成功了~
这个编码在woff文件中对应的值为7。
就是我们要找的亲人~
 
 
3 woff文件处理
事情到这里其实就可以画个句号了,因为接下来的思路就变的非常简单了,我们用上面的通用爬虫下载下网站上所有编码和对应的class值,然后根据class值找到对应的woff文件,再在woff文件中确定编码对应的数字或汉字就可以。
 
但是,当我们扩充这一思路的时候却遇到了两个问题:
1)如何读取出woff文件中的数字,大众点评有多个woff文件,怎么对照读取呢?难不成要一个个写出来?根据前面网站里的文章来讲,对的,你猜的很准,这就是我文章一开始写的半自动,崩溃了吧,好在笔者找到了新的方法,取代了半自动的问题,这个新的方法就是OCR识别,后面我会仔细讲解。
2)页面的编码是变动的,你没有看错,这个值是会变的,好在这个事件没有发生在大众点评中,但是汽车之家、猫眼等网站使用的CSS加密会随页面的刷新发生变动,有没有惊到你?
如果你只需要大众点评,第二个问题几乎可以不用考虑了,但是笔者认为要做一个有理想的爬虫,尽量多的获取知识点才是正确的,所以,笔者研究了汽车之家、猫眼、天眼等几个用CSS加密的网站,找到了一个通用的方法,下面我们来介绍一下这个通用方法。
先看一下猫眼网站上编码的动态效果:
如图:
我们先找到一个加密编码,把他复制出来,看到的编码如下:
然后我们刷新一下页面,再看源码:
不管你惊不惊,反正我是惊到了~
针对这一变化,笔者心中产生了一个疑惑,如果说编码会变,那浏览器是怎么获取到准确的值的呢?说明一定存在一个统一的方法供浏览器调用,于是,笔者重新研究了编码的调用方式,惊奇的发现了其中的秘密:
我们以如下两个编码来揭露这个今天大幂幂:
 -->unif0d5
-->unie765
这两个字段都是表示数字中的1,那他们有什么规律呢?
我们首先解码woff文件成xml格式:
from fontTools.ttLib import TTFont font = TTFont('e765.woff') font.saveXML('e765.xml')
在pycharm中我们打开xml文件:
找到unie765所在的位置:
 
这一串代码是字形坐标,浏览器就是根据这个字形坐标翻译出我们能够识别的汉字:1
同样的思路,我们再去解析unif0d5的值,得到如下图:
 
 
我们惊奇的发现,这两个竟然一样,是不是所有的值对应的字形坐标都是唯一的呢,答案是肯定的,变化的只是上图name中的编码,坐标与数字之间是一对一的,所以,我们的思路来了,我们只需要找到编码所对应的字形坐标,然后想办法解析出这个字形坐标所对应的数字就可以了。
 
 
4 完整思路
问题展示基本上清楚了,我们接下来看一下怎么自动化解决上面两个问题:
首先展示一下思路:
 
 
这是在excel里面画的,大家可以只关注内容,忽略掉背景线。
解释一下上面的思路:
首先:我们从页面上获取到文字编码和woff文件,注意,这里的字形编码和woff文件一定要一起获取,因为每个编码对应一个woff文件,一旦刷新页面,编码在woff文件中的对应关系就会变化,找不到对应的字形坐标。
data = etree.HTML(response.text) title = data.xpath('//*[@id="shop-all-list"]/ul/li[1]/div[2]/div[2]/a[1]/b/svgmtsi[1]/text()') print(title)
其次:我们把字形编码转化成uni开头的编码,并获取到woff文件中的字形坐标。
from fontTools.ttLib import TTFont font = TTFont('f0d5.woff') coordinate = font['glyf']['uniF0D5'].coordinates print(coordinate)
第三:用matplotlib解析这一坐标,并保存成图片。
#!/usr/bin/env python # _*_ UTF-8 _*_ from fontTools.ttLib import TTFont import matplotlib.pyplot as plt font = TTFont('f0d5.woff') coordinate = font['glyf']['uniF0D5'].coordinates coordinate = list(coordinate) fig, ax = plt.subplots() x = [i[0] for i in coordinate] y = [i[1] for i in coordinate] plt.fill(x, y, color="k", alpha=1) # 取消边框 for key, spine in ax.spines.items(): if key == 'right' or key == 'top' or key == 'bottom' or key == 'left': spine.set_visible(False) plt.plot(x, y) # 取消坐标: plt.axis('off') plt.savefig('uniF0D5.png') plt.show()
通过上面的解析,我们可以得到1的图片:
这个1好难看,不过好在解析出来了~
第四:使用OCR解析这个数字:
# 图片转化成string: try: from PIL import Image except ImportError: import Image import pytesseract captcha = Image.open(r'uniF0D5.png') print(captcha) result = pytesseract.image_to_string(captcha, lang='eng', config='--psm 6 --oem 3 -c tessedit_char_whitelist=0123456789').strip() print(result)
自此,我们的文字就可以直接识别出来了,我们就再也不需要用半自动的小米加步枪了,我们可以直接使用冲锋枪了
不过需要注意的是使用OCR解码文字需要一定的时间,耗时还是比较长的,如果经常使用这一思路,建议可以构建一个“字形坐标:文字”的数据库表,下次使用时解析出字形坐标,直接到数据库里匹配对应的文字就可以了。
 

Python爬虫反反爬:CSS反爬加密彻底破解!的更多相关文章

  1. [Python爬虫] 使用 Beautiful Soup 4 快速爬取所需的网页信息

    [Python爬虫] 使用 Beautiful Soup 4 快速爬取所需的网页信息 2018-07-21 23:53:02 larger5 阅读数 4123更多 分类专栏: 网络爬虫   版权声明: ...

  2. Python爬虫教程-13-爬虫使用cookie爬取登录后的页面(人人网)(下)

    Python爬虫教程-13-爬虫使用cookie爬取登录后的页面(下) 自动使用cookie的方法,告别手动拷贝cookie http模块包含一些关于cookie的模块,通过他们我们可以自动的使用co ...

  3. Python爬虫实战(2):爬取京东商品列表

    1,引言 在上一篇<Python爬虫实战:爬取Drupal论坛帖子列表>,爬取了一个用Drupal做的论坛,是静态页面,抓取比较容易,即使直接解析html源文件都可以抓取到需要的内容.相反 ...

  4. Python爬虫教程-12-爬虫使用cookie爬取登录后的页面(人人网)(上)

    Python爬虫教程-12-爬虫使用cookie(上) 爬虫关于cookie和session,由于http协议无记忆性,比如说登录淘宝网站的浏览记录,下次打开是不能直接记忆下来的,后来就有了cooki ...

  5. Python爬虫个人记录(三)爬取妹子图

    这此教程可能会比较简洁,具体细节可参考我的第一篇教程: Python爬虫个人记录(一)豆瓣250 Python爬虫个人记录(二)fishc爬虫 一.目的分析 获取煎蛋妹子图并下载 http://jan ...

  6. 爬虫--反爬--css反爬---大众点评爬虫

    大众点评爬虫分析,,大众点评 的爬虫价格利用css的矢量图偏移,进行加密 只要拦截了css 解析以后再写即可 # -*- coding: utf- -*- """ Cre ...

  7. Python爬虫学习笔记——防豆瓣反爬虫

    开始慢慢测试爬虫以后会发现IP老被封,原因应该就是单位时间里面访问次数过多,虽然最简单的方法就是降低访问频率,但是又不想降低访问频率怎么办呢?查了一下最简单的方法就是使用转轮代理IP,网上找了一些方法 ...

  8. Python爬虫入门教程: 27270图片爬取

    今天继续爬取一个网站,http://www.27270.com/ent/meinvtupian/ 这个网站具备反爬,so我们下载的代码有些地方处理的也不是很到位,大家重点学习思路,有啥建议可以在评论的 ...

  9. python爬虫(三) 用request爬取拉勾网职位信息

    request.Request类 如果想要在请求的时候添加一个请求头(增加请求头的原因是,如果不加请求头,那么在我们爬取得时候,可能会被限制),那么就必须使用request.Request类来实现,比 ...

  10. Python爬虫入门教程 6-100 蜂鸟网图片爬取之一

    1. 蜂鸟网图片--简介 国庆假日结束了,新的工作又开始了,今天我们继续爬取一个网站,这个网站为 http://image.fengniao.com/ ,蜂鸟一个摄影大牛聚集的地方,本教程请用来学习, ...

随机推荐

  1. kettle抽取数据发送邮件Linux调度

    kettle抽取数据发送邮件Linux调度 #1.进入kettle安装目录 然后执行sqoop.sh文件启动kettlecd /app/pdi-ce-7.1.0.0-12/data-integrati ...

  2. windows环境下Jmeter5.2的安装使用

    一.安装配置JDK Jmeter5.2依赖JDK1.8+版本,JDK安装百度搜索JAVA下载JDK,地址:https://www.oracle.com/technetwork/java/javase/ ...

  3. 神探Python程序员,带你千里捉小三!(附详情代码)

    前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者: 王翔 清风Python PS:如有需要Python学习资料的小伙伴 ...

  4. 爬虫selenium中动作链接ActionChains

    一.基本语法 生成一个动作actions=ActionChains(driver) 动作添加方法actions.方法 执行 actions.perform() 二.方法列表 click(on_elem ...

  5. 【重学Git】整理提交记录

    有时候我们在本分支做了一个很小的更改提交,其他分支想直接拿到这个更改提交,有没有一种不像merge或rebase这么正式的做法呢?也就是说:我仅仅是想获取其中一个小改变而已.cherry-pick就是 ...

  6. [browser location和history] 简单实现了个路由[转载]

    今天看了1下前面写的,好像缺乏交流性,周末再来弄吧 -0- 今天看了browser 的 location 和 history location属性 // //location.hash 性是一个可读可 ...

  7. Cesium专栏-视频投影(附源码下载)

    Cesium Cesium 是一款面向三维地球和地图的,世界级的JavaScript开源产品.它提供了基于JavaScript语言的开发包,方便用户快速搭建一款零插件的虚拟地球Web应用,并在性能,精 ...

  8. Jenkins自动化部署入门详细教程

    大纲 1.背景 在实际开发中,我们经常要一边开发一边测试,当然这里说的测试并不是程序员对自己代码的单元测试,而是同组程序员将代码提交后,由测试人员测试: 或者前后端分离后,经常会修改接口,然后重新部署 ...

  9. Html table 内容超出显示省略号

    内容超出显示省略号: <html> <style> table { table-layout: fixed; width: 100%; } table, th, td { bo ...

  10. Linux:VIM编辑器的使用

    打开vim编辑器 命令格式: vim 文件路径 vim编辑器的工作模式 进入编辑器后 默认为命令模式 进入输入模式 a 在光标后插入 o 换行插入 i 在光标前插入 返回命令模式 esc 键 进入末行 ...