目录
应用场景
在爬取网页数据时我们有时可能会遇到如下面的情况,价格数字在网页上能正常显示,但在控制面板查看时却是显示空白,我们通过 requests 等库爬取该页面后得到的数据也是无法显示出来。
解决思路
1.下载字体文件
我们可以去控制面板找到该网页的字体文件,双击即可下载
这里提供字体文件下载地址:字体文件
如果想要查看该字体文件,需借助字体查看软件 FontCreator 进行查看(这步可以跳过,这里只是进行查看操作)
字体查看软件下载地址:FontCreator
打开后查看:
2.分析
每个字体有它对应的id,那么我们就可以通过该id,去匹配对应的字体,最后进行输出即可。
在python通过 requests 等库获取到该无法显示的空白字符串后,通过 for 循环遍历该空白字符串,用 ord() 函数即可输出每个空白的字符对应的id,最后根据映射规则进行替换输出。
3.代码实现
版本1
速度较慢,在我本机上实测30秒完成识别
只需在 jiexi_fontFile 函数中输入对应的字体的路径即可
import time
import ddddocr
import io
import matplotlib.pyplot as plt
from fontTools.ttLib import TTFont
from fontTools.pens.freetypePen import FreeTypePen
def jiexi_fontFile(filepath):
start_time=time.time()
font = TTFont(filepath) # 解析字体文件
fontdata=font.getGlyphSet()
dic = {} # 保存识别结果的字典
ocr = ddddocr.DdddOcr(beta=True,show_ad=False) # ocr识别字体
for n, v in font.getBestCmap().items():
glyph = fontdata[v]
pen = FreeTypePen(None) # 实例化Pen子类
glyph.draw(pen) # 画出字形轮廓
b = pen.array()
iodata = io.BytesIO()
plt.imshow(b)
plt.axis('off') # 禁用坐标轴
plt.savefig(iodata, format='PNG')
plt.close()
result = ocr.classification(iodata.getvalue()) # 识别结果
dic[n] = result
print(n,'——>',result)
print('耗时:',time.time()-start_time)
print('长度:',len(dic))
return dic
print(jiexi_fontFile('96fc7b50b772f52.woff2'))
输出结果:
版本2
速度更快,在我本机上实测4秒完成识别
只需在 identify_word 函数中输入对应的字体的路径即可
import time
import ddddocr
from io import BytesIO
from PIL import Image, ImageDraw, ImageFont
from fontTools.ttLib import TTFont
def font_to_img(_code, font_path):
"""
将每个字体画成图片
:param _code:字体的数字码点
:param font_path:字体文件路径
:return: 每个字体图片对象
"""
img_size = 1024
img = Image.new('1', (img_size, img_size), 255)
draw = ImageDraw.Draw(img)
font = ImageFont.truetype(font_path, int(img_size * 0.7))
txt = chr(_code)
bbox = draw.textbbox((0, 0), txt, font=font)
x = bbox[2] - bbox[0]
y = bbox[3] - bbox[1]
draw.text(((img_size - x) // 2, (img_size - y) // 7), txt, font=font, fill=0)
return img
def identify_word(font_path):
"""
:param font_path:字体文件地址
:return:字体印射规则
"""
font = TTFont(font_path)
ocr = ddddocr.DdddOcr(beta=True)
font_mapping = {}
for cmap_code, glyph_name in font.getBestCmap().items():
bytes_io = BytesIO()
pil = font_to_img(cmap_code, font_path)
pil.save(bytes_io, format="PNG")
word = ocr.classification(bytes_io.getvalue()) # 识别字体
print(f'数字Unicode:{[cmap_code]}-{[glyph_name]}-识别结果:{word}')
# 构建字体印射规则
font_mapping[cmap_code] = word
"""去除字体印射识别为空的键值对"""
del_key = [] # 收集要删除的键
for key, value in font_mapping.items():
if not value:
del_key.append(key)
for i in del_key:
font_mapping.pop(i)
return font_mapping # 返回字体印射规则
s_t = time.time()
mapping = identify_word('96fc7b50b772f52.woff2')
print('耗时:', time.time() - s_t)
print('长度:', len(mapping))
print('字体印射规则:', mapping)
输出结果:
标签:img,Python,ddddocr,字体,time,print,import,font,FontCreator From: https://blog.csdn.net/zwq_zwq_zwq111/article/details/139526079