Python爬虫入门教程 63-100 Python字体反爬之一,没办法,这个必须写,反爬第3篇

简介: 背景交代在反爬圈子的一个大类,涉及的网站其实蛮多的,目前比较常被爬虫coder欺负的网站,猫眼影视,汽车之家,大众点评,58同城,天眼查......还是蛮多的,技术高手千千万,总有五花八门的反爬技术出现,对于爬虫coder来说,干!就完了,反正也996了~作为一个系列的文章,那免不了,依旧拿猫眼影视“学习”吧,为什么?因为它比较典型~猫眼影视打开猫眼专业版,常规操作,谷歌浏览器,开发者工具,抓取DOM节点,https://piaofang.maoyan.com/?ver=normal注意下图所有的数字位置,在DOM结构中,都是方块。

背景交代

在反爬圈子的一个大类,涉及的网站其实蛮多的,目前比较常被爬虫coder欺负的网站,猫眼影视,汽车之家,大众点评,58同城,天眼查......还是蛮多的,技术高手千千万,总有五花八门的反爬技术出现,对于爬虫coder来说,干!就完了,反正也996了~

作为一个系列的文章,那免不了,依旧拿猫眼影视“学习”吧,为什么?因为它比较典型~

猫眼影视

打开猫眼专业版,常规操作,谷歌浏览器,开发者工具,抓取DOM节点,

https://piaofang.maoyan.com/?ver=normal

注意下图所有的数字位置,在DOM结构中,都是方块。
image

字体反爬扫盲

字体反爬,是一种常见的反爬技术,网站采用了自定义的字体文件,在浏览器上正常显示,但是爬虫抓取下来的数据要么就是乱码,要么就是变成其他字符。采用自定义字体文件是CSS3的新特性,熟悉前端的同学可能知道,就是font-face属性

一些重要破解素材的收集

找到font-family属性,查看设置的内容,发现是cs字体,这明显是自定义字体了,在网页中检索cs
image

在页面的HTML源码中找到了字体的定义
image

注意文件的开头是base64 表示文件进行过base64编码,需要进行解码,然后在保存成ttf字体文件

上述截图中有个woff格式

Web开放字体格式(Web Open Font Format,简称WOFF) 是一种网页所采用的字体格式标准。此字体格式发展于2009年,现在正由万维网联盟的Web字体工作小组标准化,以求成为推荐标准。此字体格式不但能够有效利用压缩来减少档案大小,并且不包含加密也不受DRM(数位著作权管理)限制。

解码操作

import base64

font_face = "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"

print(len(font_face))

b = base64.b64decode(font_face)
with open('font.ttf','wb') as f:
    f.write(b)

对于ttf文件的处理,有3种方式,第一种使用软件 FontCreator可以直接打开ttf文件,第二种使用Python第三方库fontTools,借用这个库也可以操作ttf文件,第三种使用百度的fontstore, http://fontstore.baidu.com/static/editor/index.html

FontCreator 软件查找这个就比较简单了

你可以自行百度寻找,也可以直接打开我的百度网盘下载

链接: https://pan.baidu.com/s/1ZyWwk37hNeo0vIsTqdK2fg 提取码: kk2h

安装完毕,直接试用即可,也可以采用国家支持的和谐方法,进行和谐
image

查阅一下sources里面的html编码

image

数字进行比对
image

顺便把这个地方的编码对应关系记录一下,方便后续操作

'uniE481': '7',
'uniE0AA': '4', 
'uniF71E': '9', 
'uniE767': '1', 
'uniE031': '5', 
'uniE4BD': '2',
'uniF2AA': '3',
'uniE2E3': '6', 
'uniE3C9': '8', 
'uniEA65': '0'

数字比对完全没有问题3.69亿
image

开始编码破解字体反爬

有的网页嵌套了多套字体,增加了反爬的成本,届时自行研究即可

利用fontTools可以获取每一个字符对象,这个对象你可以简单的理解为保存着这个字符的形状信息。
而且编码可以作为这个对象的id,具有一一对应的关系。
类似猫眼电影,多套字体对应的字符的编码是变化的,但是字符的形状是不变的,也就是说这个对象是不变的。

通过fontTools进行解析字库文件

安装fonttools

pip install fonttools

fontTools库详解: https://darknode.in/font/font-tools-guide/

基本使用

from fontTools.ttLib import TTFont

font = TTFont('font.ttf')
font.saveXML('01.xml')

打开 xml 文件

开头显示的是全部编码,注意这里的ID是编号,千万不要当成对应的数字
image

下面对应的是字体信息,计算机只需要知道黑白像素点即可
image

注意事项,写代码的时候需要注意一下
image
image

关于猫眼的字体反爬做个总结

在实操中,你会发现猫眼电影,每次刷新字符编码都是变化的,但是字体的对象,也就是像素点是一致的。
image

你可以通过第一次下载一个字体文件base_font.ttf,并把对应编码的记下来,当第二次刷新页面之后,重新抓取字体文件online_font.ttf ,对比两个字体文件中的对象信息,如果对象是一样的,那么就可以知道对应的数字了。

首次获取字体文件

# 本地已经下载好的字体处理
base_font = TTFont('font.ttf') #打开本地的ttf文件

base_uni_list = base_font.getGlyphOrder()[2:]   # 获取所有编码,去除前2个,可查看前文图示

# 写出第一次字体文件的编码和对应字体
origin_dict = {'uniE481': '7', 'uniE0AA': '4', 'uniF71E': '9', 'uniE767': '1', 'uniE031': '5', 'uniE4BD': '2','uniF2AA': '3', 'uniE2E3': '6', 'uniE3C9': '8', 'uniEA65': '0'}

获取在线字体

# 获取刷新之后在线的字体

# 获取字体文件的base64编码
online_ttf_base64 = re.findall(r"base64,(.*)\) format", response)[0]
online_base64_info = base64.b64decode(online_ttf_base64)
with open('online_font.ttf', 'wb')as f:
    f.write(online_base64_info)
online_font = TTFont('online_font.ttf')  # 网上动态下载的字体文件。

online_uni_list = online_font.getGlyphOrder()[2:]


for uni2 in online_uni_list:
    obj2 = online_font['glyf'][uni2]  # 获取编码uni2在online_font.ttf中对应的对象
    for uni1 in base_uni_list:
        obj1 = base_font['glyf'][uni1]  # 获取编码uni1在base_font.ttf 中对应的对象
        if obj1 == obj2:  # 判断两个对象是否相等
            dd = "&#x" + uni2[3:].lower() + ';'  # 修改为Unicode编码格式
            if dd in response:  # 如果编码uni2的Unicode编码格式 在response中,替换成origin_dict中的数字。
                response = response.replace(dd, origin_dict[uni1])

response的获取采用的是request模块

url = 'https://piaofang.maoyan.com/?ver=normal'
headers = {
    'User-Agent': '浏览器UA',
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
}
response = requests.get(url=url, headers=headers).content  # 得到字节
charset = chardet.detect(response).get('encoding')  # 得到编码格式
response = response.decode(charset, "ignore")  # 解码得到字符串

运行结果展示

image

关注微信公众账号:非本科程序员,回复0409获取下载地址

image

相关文章
|
26天前
|
数据采集 存储 XML
Python爬虫定义入门知识
Python爬虫是用于自动化抓取互联网数据的程序。其基本概念包括爬虫、请求、响应和解析。常用库有Requests、BeautifulSoup、Scrapy和Selenium。工作流程包括发送请求、接收响应、解析数据和存储数据。注意事项包括遵守Robots协议、避免过度请求、处理异常和确保数据合法性。Python爬虫强大而灵活,但使用时需遵守法律法规。
|
27天前
|
数据采集 缓存 定位技术
网络延迟对Python爬虫速度的影响分析
网络延迟对Python爬虫速度的影响分析
|
28天前
|
数据采集 Web App开发 监控
高效爬取B站评论:Python爬虫的最佳实践
高效爬取B站评论:Python爬虫的最佳实践
|
1月前
|
数据采集 存储 JSON
Python网络爬虫:Scrapy框架的实战应用与技巧分享
【10月更文挑战第27天】本文介绍了Python网络爬虫Scrapy框架的实战应用与技巧。首先讲解了如何创建Scrapy项目、定义爬虫、处理JSON响应、设置User-Agent和代理,以及存储爬取的数据。通过具体示例,帮助读者掌握Scrapy的核心功能和使用方法,提升数据采集效率。
87 6
|
29天前
|
数据采集 存储 JSON
Python爬虫开发中的分析与方案制定
Python爬虫开发中的分析与方案制定
|
1月前
|
数据采集 JSON 测试技术
Python爬虫神器requests库的使用
在现代编程中,网络请求是必不可少的部分。本文详细介绍 Python 的 requests 库,一个功能强大且易用的 HTTP 请求库。内容涵盖安装、基本功能(如发送 GET 和 POST 请求、设置请求头、处理响应)、高级功能(如会话管理和文件上传)以及实际应用场景。通过本文,你将全面掌握 requests 库的使用方法。🚀🌟
58 7
|
1月前
|
数据采集 Web App开发 前端开发
Python爬虫进阶:Selenium在动态网页抓取中的实战
【10月更文挑战第26天】动态网页抓取是网络爬虫的难点,因为数据通常通过JavaScript异步加载。Selenium通过模拟浏览器行为,可以加载和执行JavaScript,从而获取动态网页的完整内容。本文通过实战案例,介绍如何使用Selenium在Python中抓取动态网页。首先安装Selenium库和浏览器驱动,然后通过示例代码展示如何抓取英国国家美术馆的图片信息。
76 6
|
1月前
|
数据采集 Web App开发 JavaScript
爬虫策略规避:Python爬虫的浏览器自动化
爬虫策略规避:Python爬虫的浏览器自动化
|
1月前
|
数据采集 存储 XML
Python实现网络爬虫自动化:从基础到实践
本文将介绍如何使用Python编写网络爬虫,从最基础的请求与解析,到自动化爬取并处理复杂数据。我们将通过实例展示如何抓取网页内容、解析数据、处理图片文件等常用爬虫任务。
180 1
|
1月前
|
数据采集 前端开发 中间件
Python网络爬虫:Scrapy框架的实战应用与技巧分享
【10月更文挑战第26天】Python是一种强大的编程语言,在数据抓取和网络爬虫领域应用广泛。Scrapy作为高效灵活的爬虫框架,为开发者提供了强大的工具集。本文通过实战案例,详细解析Scrapy框架的应用与技巧,并附上示例代码。文章介绍了Scrapy的基本概念、创建项目、编写简单爬虫、高级特性和技巧等内容。
64 4