阅读文本 / Reading text
本文使用合成样本演示处理方法。代码已通过隔离环境中的示例检查;这不代表对所有真实文件或产品效果的保证。处理重要文件前,请保留原件,并按文中的边界与验收项复核。
这篇先解决哪一个问题
斜体字形不必然让搜索得到的 Quad 面积小于外接矩形。需要保留四角方向信息时,直接使用 quads=True 的结果添加高亮;不要以任意面积差阈值判断高亮是否正确。
自包含的合成示例
依赖见导入列表。代码在内存中构造输入;运行记录单独提供,不代表对所有真实文件的保证。
import pymupdf
with pymupdf.open() as source:
page = source.new_page(width=300, height=300)
page.insert_text((100, 250), "Searchable", fontsize=14, rotate=90)
hits = page.search_for("Searchable", quads=True)
assert len(hits) == 1
assert isinstance(hits[0], pymupdf.Quad)
page.add_highlight_annot(hits)
assert page.search_for("Missing", quads=True) == []
raw = source.tobytes()
with pymupdf.open(stream=raw, filetype="pdf") as doc:
page = doc[0] # Keep the owning page alive while using annotations.
annotations = list(page.annots())
assert len(annotations) == 1
assert len(annotations[0].vertices) == 4
合成示例:正确输出与边界输入处理
为了验证这一行为,我们构造一个完全自包含的合成测试用例。注意,以下代码在内存中生成PDF,无需外部文件即可运行。
边界输入与错误处理:
若搜索词跨越了换行符且未被引擎识别为同一词汇单元,
search_for
可能返回空列表或仅匹配到部分片段。此时不应强行合并多个不相邻的 Quad 为一个 Rect,这会丢失中间空白区域的语义。正确的做法是保留所有返回的 Quad 片段,分别绘制高亮。另一个常见边界是搜索词包含正则特殊字符但未转义;应在调用前对输入字符串做安全处理。此外,若页面存在 CropBox 裁切,
search_for
返回的坐标仍基于未旋转的原始页面空间,恢复 CropBox 后需验证内容是否仍在可视区内,不可假定
get_text
默认忽略裁切区域。
验收标准与人工审查边界
明确不适用范围:本方案仅解决几何定位问题。若PDF本身文本层损坏、字体嵌入异常或存在隐藏图层,
search_for
的结果可能根本不可信。此类情况不属于Quads/Rects的选择问题,应交由人工审查或重新OCR。代码演示仅验证几何属性,端到端效果仍需结合具体文档类型评估。
参考资料与下一步行动
PyMuPDF Page.search_for 官方文档: https://pymupdf.readthedocs.io/en/latest/page.html#Page.search_for
PyMuPDF 坐标系说明: https://pymupdf.readthedocs.io/en/latest/page.html#coordinates
具体异常的处理决定
观察
应做什么
不应推断
搜索无命中
核对文本层与关键词
不创建空高亮
旋转文字
保留 Quad 四角
不按面积差猜测正确性
多处命中
逐项保留页号
不要只处理第一个
将这份检查清单用于文档翻译
先把页面顺序、来源位置与文本完整性检查清楚,再把同一份脱敏样本交给翻译流程。译后仍要检查标题、正文和图注是否正确对应,不能只看文字是否通顺。
OmniDoc(产品入口)
提供多格式文档翻译入口,官网介绍了 OCR、术语表与双语对照功能。对希望直接从文件开始处理的团队,这是一条值得用实际样本评估的路径。请使用有权上传的脱敏文件,并用本篇的检查项复核结果;这里不声称 OmniDoc 使用了本文的开源库或内部算法,也不以示例代替产品性能测试。
- 1 -
更新于 2026-10-08