使用Python borb库提取PDF标注遇异常,寻求解决方案
问题背景与操作流程
操作流程
- 创建简易PDF文档:
from borb.pdf import Document from borb.pdf import Page from borb.pdf import SingleColumnLayout from borb.pdf import Paragraph from borb.pdf import PDF # 创建空文档 pdf = Document() # 添加空白页面 page = Page() pdf.add_page(page) # 使用单列布局 layout = SingleColumnLayout(page) # 添加段落 layout.add(Paragraph("Hello World!")) # 保存PDF with open("output.pdf", "wb") as pdf_file_handle: PDF.dumps(pdf_file_handle, pdf)
- 用不同工具添加标注:
- 使用Linux Evince PDF阅读器3.36.10为“Hello”添加黄色高亮标注
- 使用Firefox内置PDF阅读器为“World!”添加红色下划线标注
标注效果:“Hello”文字被黄色高亮标注,“World!”被红色下划线标注
- 尝试用borb提取标注:
from borb.pdf import Document from borb.pdf import PDF # 读取文档 doc = None with open("output.pdf", "rb") as in_file_handle: doc = PDF.loads(in_file_handle) # 遍历30页提取标注 for i in range(0,30): annots = doc.get_page(i).get_annotations() print(">>> ", annots)
测试结果
- 无标注空白PDF:output.pdf
- Evince标注后的PDF:无法识别标注(output1.pdf)
- Firefox标注后的PDF:出现page(0)索引越界错误(output2.pdf)
- Firefox标注后用PDFTK新增一页的PDF:可正常读取标注(output3.pdf)
- 标注后的真实论文PDF:无法读取任何标注(test-paper.pdf)
问题分析与解决方案
异常原因
- Evince标注无法识别:部分旧版本Evince不使用标准PDF注释格式存储标注,而是采用私有结构或XFA表单存储,borb仅支持解析标准PDF注释,因此无法识别。
- Firefox标注触发索引越界:Firefox修改PDF时可能破坏了文档的页面树结构,borb的
get_page(i)依赖规范的页面树索引,结构异常时会触发索引越界;PDFTK新增页面后修复了页面树,因此能正常读取。 - 真实论文PDF无法读取标注:可能是以下原因:
- 标注存储在非标准字段(如附件层、自定义元数据)中;
- PDF被加密或设置了注释读取权限;
- 论文使用复杂页面布局(分栏、嵌套结构),导致borb的注释解析逻辑无法匹配。
正确提取标注的方法
1. 优化标注读取代码
避免固定遍历页数,先获取实际页数并增加异常处理:
from borb.pdf import Document from borb.pdf import PDF # 读取文档 doc = PDF.loads(open("your_file.pdf", "rb")) # 遍历所有有效页面 total_pages = doc.get_number_of_pages() for page_num in range(total_pages): try: page = doc.get_page(page_num) annotations = page.get_annotations() if annotations: print(f"第{page_num+1}页标注:{annotations}") else: print(f"第{page_num+1}页无标注") except Exception as e: print(f"读取第{page_num+1}页失败:{str(e)}")
2. 处理非标准标注(Evince)
- 更新Evince到最新版本,新版本默认使用标准PDF注释格式;
- 使用Poppler工具包的
pdfinfo或pdf2txt.py提取注释元数据,辅助解析。
3. 修复损坏的PDF结构(Firefox)
先使用Ghostscript或PDFTK修复PDF结构,再用borb读取:
# 使用Ghostscript修复 gs -o fixed_output.pdf -sDEVICE=pdfwrite -dPDFSETTINGS=/prepress broken_input.pdf
4. 处理加密/复杂PDF
- 若PDF加密,先使用
qpdf解密:
qpdf --password=your_password --decrypt encrypted.pdf decrypted.pdf
- 对于复杂布局的PDF,配合borb的
TextExtraction工具定位标注对应的文本区域,关联注释内容。
内容的提问来源于stack exchange,提问作者Yan King Yin
相关产品推荐
相关产品推荐

