>>>hex(40857)
'0x9f99'
答案是:字体编辑器的上面这个编码【$9F99】,正是【40857】的十六进制表示。
所以,现在我们知道了,【uni9F99】这个注释对应的字体就是【八】,也能通过fontTools找到这个对应关系,但是我们现在还不知道的是:哪个源代码的字体要替换成【八】
回到我们刚才打开的政策网页,【申报材料】里,正好也有一个【八】
很显然,源代码的【龙】字,实际展示时,为【八】这个汉字
所以,源代码里:龙要替换成八
那么前端代码在处理和展示的时候,怎么知道龙要替换成八,或者说替换成八这个字体图形?
显然是有一套通用的处理规则,我们现在就是要找出这套转换规则
从【龙】这个汉字入手:
【龙】utf8编码为【\xe9\xbe\x99】
【龙】gbk编码为【\xc1\xfa】
【龙】的Ascii数值为【40857】
>>>ord('龙')
40857
40857!刚才我们使用getBestCmap返回的字典,【40857】正好对应的值是【uni9F99】,对应的字体正好是【八】!
所以汉字【龙】> ord(‘龙’) > 40857
现在我们只剩最后一个问题:
如何批量构建,类似于这种【40857/$9F99/uni9F99】与【八】的对应关系?
答案是:手动构建!
当然,也不是完全手动构建类似 {‘uni9F99’: ‘八’, ‘six’: ‘6’, … ,} 这种字典
有一种取巧的方式:
fontTools库的getGlyphOrder() 方法,可以获取字体文件的所有字体注释
该方法返回的字体注释的列表,与百度字体编辑器展示的顺序是一模一样的
>>>font_file.getGlyphOrder()
['.notdef', 'nine', 'eight', 'three', 'four', 'seven', ..., 'uni9662', 'uni660E']
下图为手动构建的完整的FONT_LIST(要对应百度字体编辑器)

上文所说的手动构建,就是指,把百度字体编辑器展示的字体,一个一个对应着写到一个列表里,保存起来,以后若是网站字体又有所更新,只需要修改相应的元素即可。
所以这里我们只需要手动按顺序构建字体对应的列表FONT_LIST,即可生成对应的字典
>>>FONT_LIST = [' ', '9', '8', '3', '4', '7', ..., '明', '局', '第']
>>>font_dict = dict(zip(font_file.getGlyphOrder(), FONT_LIST))
>>>font_dict
{'.notdef': ' ',
'nine': '9',
'eight': '8',
'three': '3',
'four': '4',
'seven': '7',
...
'uni7B2C': '业',
'uni3007': '院',
'uni4E1A': '⚪',
'uni5C40': '明',
'uni9662': '局',
'uni660E': '第'}
这个font_dict有什么用呢,这还要和前文的getBestCmap方法配合起来使用
>>>replace_dict = {}
>>>for code, value in font_file['cmap'].getBestCmap().items():
>>> before_replace = chr(code)
>>> after_replace = font_dict[value]
>>> replace_dict[before_replace] = after_replace
>>>replace_dict
{'!': '&',
'#': '>',
'$': 'c',
'%': '~',
'&': 'H',
'(': 'q',
...
'革': '策',
'项': '不',
'须': '制',
'额': '司',
'首': '免',
'验': '省',
'高': '天',
'龙': '八'}
这个replace_dict就是我们最终的用来替换文本的字典了。
到此,我们的实操就结束了,下面进入整体流程的代码部分。
from fontTools.ttLib import TTFont
FONT_FILE = r'C:\Users\17337\Downloads\ccw.ttf'
FONT_LIST = [' ', '9', '8', '3', '4', '7', ..., '明', '局', '第']
def get_font():
font_file = TTFont(FONT_FILE)
font_dict = dict(zip(font_file.getGlyphOrder(), FONT_LIST))
return {chr(k): font_dict[v] for k, v in font_file['cmap'].getBestCmap().items()}
def change(text):
replace_dict = get_font()
return ''.join([replace_dict.get(each, each) for each in text]) if text else ''
def test():
chace_str = '者合册第应具步以督法快:'
result = change(chace_str)
print('转换前:"{}", 转换后:"{}"'.format(chace_str, result))
if __name__ == '__main__':
test()
文章中,本人提供了一种字体反爬的解决方案,当然,也有该方案的缺陷:
1.需要手动构建FONT_LIST列表,比较花费时间
2.适用于某一特定网,但不一定适用于其他网站,不能作为一种普适的字体反爬的解决方案
感谢您的观看!
什么是字体反爬?
所谓的字体反爬就是网站一些关键字替换成自己设计的字体,这样用浏览器访问网站的时候会加载这套字体,因此在浏览器中显示是正常的字体;而在源码中这些关键字是乱码的,根本无法识别,采集下来是无用的信息
使用字体反爬的例子:抖音、大众点评、58等,如下是抖音的
解决字体反爬,以抖音为例
1 提取抖音个人主页链接
个人主页—>右上角—>分享—>复制链接,在浏览器...
爬取一些网站的信息时,偶尔会碰到这样一种情况:网页浏览显示是正常的,用python爬取下来是乱码,F12用开发者模式查看网页源代码也是乱码。这种一般是网站设置了字体反爬
这里我们以58同城为例:
点击进入https://sz.58.com/chuzu/链接:
网页显示数据为:
网页原码数据为:
从上面可以看出,生这个字变成了乱码,请大家特别注意箭头所指的数字。
在这里里我...
所以我现在要做的就是,怎么去将&#x…;字符转为对应的汉字。
先手动下载页面中的字体文件。然后使用fontTools模块,读取字体文件,并将其保存为xml格式(正常情况下,字体文件是无...
前几天在一个论坛上,看见ALT+821206(小键盘)能输入一个“囍”字,挺有意思的。实际上是,汉字编码、内码的一些东西。下面是一些常用的:猴(ALT+29492) 鸡(ALT+40481) 狗(ALT+29399) 猪(ALT+29482) 鼠(ALT+40736) 牛(ALT+29275) 虎(ALT+34382) 兔(ALT+208
前言:字体反爬,也是一种常见的反爬技术,例如58同城,猫眼电影票房,汽车之家,天眼查,实习僧等网站。这些网站采用了自定义的字体文件,在浏览器上正常显示,但是爬虫抓取下来的数据要么就是乱码,要么就是变成其他字符,是因为他们采用自定义字体文件,通过在线加载来引用样式,这是CSS3的新特性,通过 CSS3,web 设计师可以使用他们喜欢的任意字体 ,然后因为爬虫不会主动加载在线的字体,
字体加密一般是网页修改了默认的字符编码集,在网页上加载他们自己定义的字体文件作为字体的样式,可以正确地显示数字,但是在源码上同
页面在css中使用font-face定义了字符集,并通过unicode去映射展示,浏览器会加载css中的font字体为用户渲染好,所以浏览页面时是正常的,而对于爬虫来说却极其不友好,因为爬取下来的源代码未经过浏览器渲染,都是乱码。
1. 查找到页面中的加密字体 font_face,常见的有两种情况
1.最简单的,直接在页面源码中搜索font_face,如果能找到类似如
此篇博客为普通方式爬取安居客租房数据一共提取出1200条,但是在进行大规模的数据爬取时,不建议使用这种方式,速度太慢是最大的诟病,在进行大规模爬取时,使用分布式爬虫是第一选择
一、指定爬取数据
二、设置请求头防止反爬
三、分析页面并且与网页源码进行比对
四、分析页面整理数据
五、保存到excel表中
六、使用jupyternotebook进行简单的数据分析
一、指定爬取数据
提取价格、面积、详细标题、名称、具体位置、房屋结构、装修情况
二、设置请求头
这里设置请求头依然使用最常见的.
2. 字体反爬
2.1 字体反爬简介
在 CSS3 之前,Web 开发者必须使用用户计算机上已有的字体。目前的技术开发者可以使用@font-face为网页指定字体,开发者可将心仪的字体文件放在 Web 服务器上,并在 CSS 样式中...
可见无论是小说文字数量还是推荐数,在我们本来页面中是好好的,可在网页源码中是一对我们看不懂的字体,这其实就是字体加密,所以我想做到字体反扒,就要破解字体加密,接下来我会为大家一一概述。
2、网页爬取代码
内容过于简单,不做过多概述
import requests
headers = {
"user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/53..
通过这个爬虫,个人觉得代码层面是不难的,难在请求参数的解析,cookie的解析,js逆向,登录验证码解析等各种反爬虫手段,不过道高一尺,魔高一丈,总归有解决的办法!!!其次文章中,对于cookie的值我并没有进行讲解,这个根据自己实际需求进行测试,那么多的cookie不可能全都有用,大家可以通过postman对cookie的值进行删减直到获取不到数据为之!总的说请求头信息,cookie等信息并不是全部都需要传递!