猫眼电影,自定义字体解决方法
猫眼破解数字反爬获取实时票房
一、概览
自前期写过汽车之家字体反爬破解实践之后,发现字体反爬应用还是很普遍。这两天有知乎朋友咨询如何实现猫眼票房数据的爬取,这里其实与上面的文章核心思想是一致的,但是操作更复杂一些,本文做一个更详细的破解实践。
有对字体反爬还比较陌生的,请参考前文。
二、查找字体源
猫眼电影是美团旗下的一家集媒体内容、在线购票、用户互动社交、电影衍生品销售等服务的一站式电影互联网平台。2015年6月,猫眼电影覆盖影院超过4000家,这些影院的票房贡献占比超过90%。目前,猫眼占网络购票70%的市场份额,每三张电影票就有一张出自猫眼电影,是影迷下载量较多、使用率较高的电影应用软件。同时,猫眼电影为合作影院和电影制片发行方提供覆盖海量电影消费者的精准营销方案,助力影片票房。
我们使用Chrome浏览页面,并查看源码,发现票房中涉及数字的,在页面显示正常,在源码中显示一段span包裹的不可见文本。
上面其实就是自定义字体搞的鬼。根据网页源码中,
<span class="stonefont">.</span>
使用了自定义的stonefont字体,我们在网页中查找stonefont,很快有了发现,这就是标准的@font-face定义方法。且每次访问,字体文件访问地址都会随机变化。
我们访问其中woff文件的地址,可将woff字体文件下载到本地。前文中fonttools并不能直接解析woff字体,我们需要将woff字体转换成otf字体。还好,在github上找到了python转换工具woff2otf,成功实现字体的转换。
三、字体解析
otf就是我们常用的字体文件,可以使用系统自带的字体查看器查看,但是难以看到更多有效的信息,我们使用一个专用工具Font Creator查看。
可以看到,这个字体里有12个字(含一个空白字),每个字显示其字形和其字形编码。这里比之前字体解析更复杂的是,这里不仅字体编码每次都会变,字体顺序每次也会变,很难直接通过编码和顺序获取实际的数字。
因此,我们需要预先下载一个字体文件,人工识别其对应数值和字体,然后针对每次获取的新的字体文件,通过比对字体字形数据,得到其真实的数字值。
下面是使用fontTools.ttLib获取的单个字符的字形数据。
<TTGlyph name="uniE183" xMin="0" yMin="-12" xMax="516" yMax="706"><contour><pt x="134" y="195" on="1"/><pt x="144" y="126" on="0"/><pt x="217" y="60" on="0"/><pt x="271" y="60" on="1"/><pt x="335" y="60" on="0"/><pt x="423" y="158" on="0"/><pt x="423" y="311" on="0"/><pt x="337" y="397" on="0"/><pt x="270" y="397" on="1"/><pt x="227" y="397" on="0"/><pt x="160" y="359" on="0"/><pt x="140" y="328" on="1"/><pt x="57" y="338" on="1"/><pt x="126" y="706" on="1"/><pt x="482" y="706" on="1"/><pt x="482" y="622" on="1"/><pt x="197" y="622" on="1"/><pt x="158" y="430" on="1"/><pt x="190" y="452" on="0"/><pt x="258" y="475" on="0"/><pt x="293" y="475" on="1"/><pt x="387" y="475" on="0"/><pt x="516" y="346" on="0"/><pt x="516" y="243" on="1"/><pt x="516" y="147" on="0"/><pt x="459" y="75" on="1"/><pt x="390" y="-12" on="0"/><pt x="271" y="-12" on="1"/><pt x="173" y="-12" on="0"/><pt x="112" y="42" on="1"/><pt x="50" y="98" on="0"/><pt x="42" y="188" on="1"/></contour><instructions/></TTGlyph>
使用下面语句可以获取顺序的字符编码值,
# 解析字体库font文件
baseFont = TTFont('base.otf')
maoyanFont = TTFont('maoyan.otf')
uniList = maoyanFont['cmap'].tables[0].ttFont.getGlyphOrder()
numList = []
baseNumList = ['.', '3', '5', '1', '2', '7', '0', '6', '9', '8', '4']
baseUniCode = ['x', 'uniE64B', 'uniE183', 'uniED06', 'uniE1AC', 'uniEA2D', 'uniEBF8',
'uniE831', 'uniF654', 'uniF25B', 'uniE3EB']
for i in range(1, 12):maoyanGlyph = maoyanFont['glyf'][uniList[i]]for j in range(11):baseGlyph = baseFont['glyf'][baseUniCode[j]]if maoyanGlyph == baseGlyph:numList.append(baseNumList[j])break
四、内容替换
关键点攻破了,整个工作就好做了。先访问需要爬取的页面,获取字体文件的动态访问地址并下载字体,读取用户帖子文本内容,替换其中的自定义字体编码为实际文本编码,就可复原网页为页面所见内容了。
完整代码如下:
# -*- coding:utf-8 -*-
import requests
from lxml import html
import re
import woff2otf
from fontTools.ttLib import TTFont#抓取maoyan票房
class MaoyanSpider:#页面初始化def __init__(self):self.headers = {"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8","Accept-Encoding": "gzip, deflate, br","Accept-Language": "zh-CN,zh;q=0.8","Cache-Control": "max-age=0","Connection": "keep-alive","Upgrade-Insecure-Requests": "1","Content-Type": "application/x-www-form-urlencoded; charset=UTF-8","User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.86 Safari/537.36"}# 获取票房def getNote(self):url = "http://maoyan.com"host = {'host':'maoyan.com','refer':'http://maoyan.com/news',}headers = dict(self.headers.items() + host.items())# 获取页面内容r = requests.get(url, headers=headers)#print r.textresponse = html.fromstring(r.text)# 匹配ttf fontcmp = re.compile(",\n url\('(//.*.woff)'\) format\('woff'\)")rst = cmp.findall(r.text)ttf = requests.get("http:" + rst[0], stream=True)with open("maoyan.woff", "wb") as pdf:for chunk in ttf.iter_content(chunk_size=1024):if chunk:pdf.write(chunk)# 转换woff字体为otf字体woff2otf.convert('maoyan.woff', 'maoyan.otf')# 解析字体库font文件baseFont = TTFont('base.otf')maoyanFont = TTFont('maoyan.otf')uniList = maoyanFont['cmap'].tables[0].ttFont.getGlyphOrder()numList = []baseNumList = ['.', '3', '5', '1', '2', '7', '0', '6', '9', '8', '4']baseUniCode = ['x', 'uniE64B', 'uniE183', 'uniED06', 'uniE1AC', 'uniEA2D', 'uniEBF8','uniE831', 'uniF654', 'uniF25B', 'uniE3EB']for i in range(1, 12):maoyanGlyph = maoyanFont['glyf'][uniList[i]]for j in range(11):baseGlyph = baseFont['glyf'][baseUniCode[j]]if maoyanGlyph == baseGlyph:numList.append(baseNumList[j])breakuniList[1] = 'uni0078'utf8List = [eval("u'\u" + uni[3:] + "'").encode("utf-8") for uni in uniList[1:]]# 获取发帖内容movie_name = response.cssselect(".ranking-box-wrapper li .ranking-top-moive-name")[0].text_content().replace(' ', '').replace('\n', '').encode('utf-8')movie_wish = response.cssselect(".ranking-box-wrapper li .ranking-top-wish")[0].text_content().replace(' ', '').replace('\n', '').encode('utf-8')print movie_name, movie_wishprint '---------------after-----------------'for i in range(len(utf8List)):movie_wish = movie_wish.replace(utf8List[i], numList[i])print movie_name, movie_wishspider = MaoyanSpider()
spider.getNote()
解析访问,获取票房数据。
五、参考文章
1、汽车之家字体反爬破解实践 (https://zhuanlan.zhihu.com/p/32087297)
2、fontTools.ttLib用法
http://pyopengl.sourceforge.net/pydoc/fontTools.ttLib.html
3、fonttools源码 (https://github.com/fonttools/fonttools)
附录
猫眼破解数字反爬获取实时票房源代码:点这里,密码:cp2j
猫眼电影,自定义字体解决方法相关推荐
- h5页面自定义字体_H5自定义字体解决方法(mark)
应用情景 业务搬砖需求需要用原设计稿给出的字体,使用@font-face引入后,发现字体包太大10M左右,每次请求服务器10M流量会造成服务器压力,影响用户体验 第一步:使用@font-face MD ...
- requests爬取猫眼电影403错误解决方法
原代码如下: import requests from requests.exceptions import RequestExceptiondef one_page_code(url):try:pa ...
- 微信小程序访问豆瓣电影api400错误解决方法
微信小程序访问豆瓣电影api400错误解决方法 参考文章: (1)微信小程序访问豆瓣电影api400错误解决方法 (2)https://www.cnblogs.com/bubbleStar/p/610 ...
- Ubuntu20.04安装WPS Office 2019 For Linux教程及缺失字体解决方法
Ubuntu20.04安装WPS Office 2019 For Linux教程及缺失字体解决方法 注:本文是作为记录,方便以后重装系统后再次安装,放出来供大家参考,遇到问题可以留言,看到后会解答.另 ...
- python爬取b站搜索结果_Python爬虫实例:爬取猫眼电影——破解字体反爬,Python爬虫实例:爬取B站《工作细胞》短评——异步加载信息的爬取,Python爬虫实例:爬取豆瓣Top250...
字体反爬 字体反爬也就是自定义字体反爬,通过调用自定义的字体文件来渲染网页中的文字,而网页中的文字不再是文字,而是相应的字体编码,通过复制或者简单的采集是无法采集到编码后的文字内容的. 现在貌似不少网 ...
- Python爬虫实例:爬取猫眼电影——破解字体反爬
字体反爬 字体反爬也就是自定义字体反爬,通过调用自定义的字体文件来渲染网页中的文字,而网页中的文字不再是文字,而是相应的字体编码,通过复制或者简单的采集是无法采集到编码后的文字内容的. 现在貌似不少网 ...
- Ubuntu 16.04-18.04中安装 WPS Office 2016 for Linux(集合篇含字体解决方法)简单好用
金山软件办公套件的最新更新 WPS 2016 for Linux,日前发布了几项新功能,性能改进和各种修复. 为什么选择WPS办公套件? WPS Office由三个主要组件组成:WPS 文字,WPS ...
- iOS游戏开发中使用自定义字体的方法
方法1: 添加对应的字体(.ttf或.odf)到工程的resurce,使用cocos2d中的FontLabel库,FontLabel继承于UILabel,象UILabel一样使用就好了 fontNam ...
- itext生成pdf文档加载中文字体解决方法
最近接手一个任务,在网页中通过用户的输入的信息生成一个pdf文档并且下载到用户本地.iText是用于生成PDF文档的一个java类库.通过iText不仅可以生成PDF或rtf的文档,而且可以将XML. ...
最新文章
- IndentationError: unexpected indent python
- noj数据结构稀疏矩阵的加法十字链表_一个算法毁了一款好游戏?算法和数据结构到底有多重要?...
- 怎么看电脑电源多少w_电脑电源供电不足会怎么样 电脑电源供电不足坏处介绍【详解】...
- 如何查看crontab的日志记录
- 对话图森无人车CEO陈默:IPO,我们只差最后一个必要条件
- 相机上的AE AF AWB AEB都表示的是什么?
- ahjesus 创建msdn一样的帮助文档
- Create new SAP DDL view and click finish in wizard
- Android之使用Intent跳转到一个网页
- matlab三角函数降次,三角函数降次公式及推导过程
- Java还有发展前景吗?现在该怎么去学习?
- 【黑马Bootstrap笔记】Bootstrap快速入门
- datetime与timestamp的区别
- 【已解决】Nginx基于多端口、多域名配置
- 雍正《连平州志·序》:揭秘连平起源之迷
- 全球及中国轮胎行业发展方向与销售前景状况分析报告2022年
- c语言代码怎样制作成一个游戏?
- 回炉再造Css Layout
- 二硫化钼量子点修饰纳米金棒/CdS纳米棒|二硫化钼量子点/g-C3N4复合光催化剂|马来酰亚胺修饰二硫化钼MoS2-MAL
- 定义一个学生信息结构体,包含姓名,学号,语文成绩、数学成绩,和英语成绩,定义结构体数组存放不同学生的信息,可以在终端录入学生的信息,在基础上添加一个计算平均值和按照平均值排序以及删除指定学号的学生信息