前一段时间,爬取了58同城,发现当时的网页对数字有字体反爬虫,然后废了九牛二虎之力找到了规律,终于破解了反爬虫,后来发现猫眼的这个网页虽然使用了字体反爬,但是和原来的58同城还是有很大的差别,后来了解到这个新的字体反爬虫属于动态字体加载。

首先我们登陆上猫眼的首页,然后可以看到

本来应该正常显示数字的部分,变成了一组我们看不懂的文本格式,然后我们去查看源码

发现在源码中是以html编码编写的,同时我们也可以在网页中找到

这个就是整个猫眼网页中使用的字体文本,所以我们需要花费很大的精力在这一部分,这个也是破解这个动态字体反爬的关键必要操作。

我们需要使用到一个叫做fontcreator的应用,可以自行在网上下载一下。

我们将这个应用下载下来,然后将上图中的

//vfile.meituan.net/colorstone/726c02e5f18a0632020d0d5c82ec81b72088.woff

这一段代码提取出来,然后组成一个url,用Python将网页中的信息提取出来,以为二进制的形式保存在.woff文件中,将其作为基础字体模板,用来比较后面的字体。

    def write_file(self,response_woff):#存储woff字体文件with open('get_fonts.woff','wb')as f:f.write(response_woff)

然后用刚刚下载的应用将这个woff文件打开。

我们将这个.woff文件命名为basefonts.woff,其目地就是为了对比以后获取到的字体woff文件。

baseFonts = TTFont('basefonts.woff')base_nums = ['1', '6', '5', '0', '7', '9', '8', '4', '2', '3']base_fonts = ['uniF2DD', 'uniF747', 'uniF01C', 'uniEBD0', 'uniEA1B', 'uniE897', 'uniE477', 'uniF53B', 'uniF1DF','uniE38B']

以上我么就完成了将字体模板解析和缓存在本地。

接下来,我们刷新网页,可以发现woff字体发生了改变,

我们对比两组字体发现对应的Unicode编码也并不相同,但是我们将.woff文件转换成xml文件,可以找到一定的规律。

font = TTFont("basefonts.woff")
font.saveXML('basefonts.xml')

我们将两个woff文件 都转换成xml格式,打开以后可以看到其中,对于字体笔画顺序的编写是相同的,

所以我们可以找出相应的规律,将先后得到的代码进行一一对应,就可以找出每一次加载出来的字体有什么变化规律。

base_nums = ['1', '6', '5', '0', '7', '9', '8', '4', '2', '3']base_fonts = ['uniF2DD', 'uniF747', 'uniF01C', 'uniEBD0', 'uniEA1B', 'uniE897', 'uniE477', 'uniF53B', 'uniF1DF','uniE38B']onlineFonts = TTFont('get_fonts.woff')#经过观察字体本身可以发现规律,第一个为None,最后一个也为None值,所以需要处理掉uni_list = onlineFonts.getGlyphNames()[1:-1]temp = {}#因为字体是动态加载出来的,所以需要实现字体的一一对应:for i in range(10):onlineGlyph = onlineFonts['glyf'][uni_list[i]]for j in range(10):baseGlyph = baseFonts['glyf'][base_fonts[j]]if onlineGlyph == baseGlyph:temp["&#x" + uni_list[i][3:].lower() + ';'] = base_nums[j]

最后,我们就可以分析出整个动态字体反爬的心路历程了。

# -*- coding: utf-8 -*-
# Created : 2019/4/1import re
import requests
from fontTools.ttLib import TTFont
from lxml import etreeclass Maoyanspider:def __init__(self):self.headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.96 Safari/537.36",}def parse_fonts(self,url):#获取网页源码response = requests.get(url,headers = self.headers).text#获取网页动态加载的字体模板self.get_font(response)#字体手动获取到的网页字体模板baseFonts = TTFont('basefonts.woff')base_nums = ['1', '6', '5', '0', '7', '9', '8', '4', '2', '3']base_fonts = ['uniF2DD', 'uniF747', 'uniF01C', 'uniEBD0', 'uniEA1B', 'uniE897', 'uniE477', 'uniF53B', 'uniF1DF','uniE38B']onlineFonts = TTFont('get_fonts.woff')#经过观察字体本身可以发现规律,第一个为None,最后一个也为None值,所以需要处理掉uni_list = onlineFonts.getGlyphNames()[1:-1]temp = {}#因为字体是动态加载出来的,所以需要实现字体的一一对应:for i in range(10):onlineGlyph = onlineFonts['glyf'][uni_list[i]]for j in range(10):baseGlyph = baseFonts['glyf'][base_fonts[j]]if onlineGlyph == baseGlyph:temp["&#x" + uni_list[i][3:].lower() + ';'] = base_nums[j]#将被处理过的字体进行替换pat = '(' + '|'.join(temp.keys()) + ')'response_index = re.sub(pat, lambda x: temp[x.group()], response)#最终返回的是一个处理过(信息正常)的网页源码return response_indexdef get_font(self,response):#提取出woff文件,存储在本地woff = re.search(r"url\('(.*\.woff)'\)", response).group(1)woff_url = 'http:' + woffresponse_woff = requests.get(woff_url, headers=self.headers).contentself.write_file(response_woff)def write_file(self,response_woff):#存储woff字体文件with open('get_fonts.woff','wb')as f:f.write(response_woff)font = TTFont("basefonts.woff")font.saveXML('basefonts.xml')def parse_url(self,response):#该response是已经处理过的网页源码,可以直接操作html = etree.HTML(response)ul_list = html.xpath('//ul[@class="ranking-wrapper ranking-box"]/li')content_list = []for ul in ul_list:item = {}#获取影片票房movie_price = ul.xpath(".//span[@class='stonefont']/text()")[0]#获取影片名称movie_name = ul.xpath(".//span[@class='ranking-top-moive-name']/text()|.//span[@class='ranking-movie-name']/text()")[0]movie_price_unit ="".join(ul.xpath(".//p[@class='ranking-top-wish']/text()|.//span[@class='ranking-num-info']/text()")).replace("\n","").replace(" ","")item['movie_name'] = movie_nameitem['movie_price'] = movie_price + movie_price_unitcontent_list.append(item)return content_list#将信息打印出来,也可以选择存储在数据库中def print_movie_info(self,content_list):for content in content_list:print(content)def run(self):#输入需要获取的网页url = 'https://maoyan.com/'#将网页信息提取出来,将被处理过的字体进行反处理后解析出来response = self.parse_fonts(url)#获取需要的信息content_list = self.parse_url(response)self.print_movie_info(content_list)if __name__ == '__main__':maoyan = Maoyanspider()maoyan.run()

如有问题,欢迎斧正!

联系qq:986361369

python爬取猫眼遇到动态字体反爬相关推荐

  1. Python爬虫实例:爬取猫眼电影——破解字体反爬

    字体反爬 字体反爬也就是自定义字体反爬,通过调用自定义的字体文件来渲染网页中的文字,而网页中的文字不再是文字,而是相应的字体编码,通过复制或者简单的采集是无法采集到编码后的文字内容的. 现在貌似不少网 ...

  2. python爬取b站搜索结果_Python爬虫实例:爬取猫眼电影——破解字体反爬,Python爬虫实例:爬取B站《工作细胞》短评——异步加载信息的爬取,Python爬虫实例:爬取豆瓣Top250...

    字体反爬 字体反爬也就是自定义字体反爬,通过调用自定义的字体文件来渲染网页中的文字,而网页中的文字不再是文字,而是相应的字体编码,通过复制或者简单的采集是无法采集到编码后的文字内容的. 现在貌似不少网 ...

  3. python爬虫爬取58网站数据_Python爬虫,爬取58租房数据 字体反爬

    Python爬虫,爬取58租房数据 这俩天项目主管给了个爬虫任务,要爬取58同城上福州区域的租房房源信息.因为58的前端页面做了base64字体加密所以爬取比较费力,前前后后花了俩天才搞完. 项目演示 ...

  4. python爬取大众点评字体_python爬取大众点评解决字体反爬

    今天我们弄一下大众点评 学习阶段,我们要抱着学习的目的 重点是思路,做爬虫就不要想着一劳永逸了 方法公开,人家就换了 知识是你自己的,学到了,他换不掉 好了,我们开始吧 网站展示 https://ww ...

  5. k-近邻算法 解决 动态字体反爬

    记录k-近邻算法 解决猫眼电影的字体反爬. 此博客仅为我业余记录文章所用,发布到此,仅供网友阅读参考,如有侵权,请通知我,我会删掉. 文章有一些点没有说的很细.因为我相信能看到这篇文章的你,不通过我的 ...

  6. python爬虫: 使用knn算法破解猫眼动态字体反爬

    猫眼字体反爬 动态变化的字形使用阈值判断误差率较大,甚至看到有的老哥使用ocr去搞-,大概两个月前,第一次看到有大佬使用knn算法搞字体反爬(源码地址),听说效果不错,一直没有时间去尝试,不仅仅是没有 ...

  7. 爬取58同城,解决反爬字体加密解析问题

    [导语]我们在爬取数据中,会遇到字体乱码的下,其实是字体加密,本篇文章主要解决字体解密这种反爬方式. 1.在浏览器打开58同城网址进入北京租房 2.点击检查,找到房租价格对应位置,发现源码中价格部分是 ...

  8. 用python爬取有道翻译遇到反爬,3分钟反反爬绕过其反爬

    利用有道翻译的接口,自制一个翻译程序 查看其翻译接口,发现post请求需要传很多参数,而且经过测验,satl,sigh属于动态生成的,遇到这种问题怎么办?当然有时间的情况下,可以去研究这些参数在哪个响 ...

  9. python爬虫反爬策略_抖音字体反爬,爬虫字体反爬策略——每周一个爬虫小教程系列...

    在B站上看到一个关于抖音字体反爬的视频,看完之后,精神抖擞,不禁感觉,我又行了,于是在模拟器上下载了一个抖音,打开了我尘封已久的抖音号. 可以看见显示的数字是正常的,但是查看源码就是错误的. 既然是字 ...

最新文章

  1. ggplot2 图形排版:patchwork 包复杂排版
  2. 机器人用上AI后,拥有了堪比人类皮肤的触觉:轻松引线穿针、夹取鸡蛋丨Science子刊...
  3. Linux命令学习之nslookup
  4. Xcode9新特性介绍-中文篇
  5. php判断目录是否有写的权限,php中判断文件空目录是否有读写权限的函数代码_php技巧...
  6. php的create_function、function_exists判断函数是否存在
  7. java中Object和Objects类、toString方法和equals方法介绍
  8. 电脑设置代理IP工具 可自动更新
  9. 高并发编程-07-JDK提供的原子类操作及原理
  10. 适配器模式的极简概述
  11. 运动目标跟踪(十三)--SRDCF/DeepSRDCF
  12. LINUX编译libusb
  13. debian的中国镜像
  14. 面试被问如何保证缓存与数据库的双写一致性?这篇帮你搞定
  15. 掘金mysql_MySQL学习笔记(转自掘金小册 MySQL是怎样运行的,版权归作者所有!)
  16. python动态心形代码-python心形代码
  17. Python:2行代码实现文字转语音
  18. 20155313 杨瀚 《网络对抗技术》实验四 恶意代码分析
  19. Tableau 桑基图
  20. 腾讯云安装配置数据库MySQL并且使用SQLyog连接

热门文章

  1. OTA升级常见问题及流程
  2. python中可迭代对象是什么意思_python可迭代对象概念讲解
  3. Arduino小白的学习历程
  4. python 协程库gevent学习 -- 超时、互斥锁(BoundedSemaphore)、local
  5. 海云安应用安全测试、移动应用安全、开发安全再次上榜
  6. oracle 怎么截取中文,oracle 截取字符(substr)
  7. 2022-2028全球与中国健康资讯交换(HIE)市场现状及未来发展趋势
  8. /home/ljx/miniconda3/compiler_compat/ld: cannot find crtbeginS.o: 没有那个文件或目录
  9. pandas将df赋值到另一个df_Python/Pandas:如果匹配的話,將一個df的值添加到另一個df的行的末尾...
  10. linux服务器强制关机,Mac强制关机的4种方法以备不时之需