pdfrw读取PDF表单字段缺失:指定字段无法提取求助
问题:PDF表单字段提取遗漏'Date of Birth'、'Beneficial Owner Name'等字段
我编写的read_pdf_form函数本该读取'Date of Birth'、'Beneficial Owner Name'等PDF表单字段,但这些字段被遗漏。尝试过添加文档遍历循环、设置页面约束、重命名PDF字段,均无效果,反而使代码复杂化,因此恢复了原函数。
原函数代码
def read_pdf_form(path_to_pdf): pdf = PdfReader(path_to_pdf) annotations = [ann for page in pdf.pages for ann in page.Annots or []] field_values = {ann.T[1:-1]: ann.V[1:-1] if ann.V else '' for ann in annotations if ann.T} print("Extracted field values from PDF:", field_values, "\n") return field_values
当前提取结果
提取到的字段结果:
{'Name of Investor': 'Unfilled', 'US TIN': 'Unfilled', 'Type of Subscriber': 'Unfilled', 'Controlling Individual Email': 'Unfilled', 'brendan': '', 'Advisor Name': 'Unfilled', 'Advisor Rep Number': 'Unfilled', 'Commitment Amount': 'Unfilled', 'Bank Name': 'Unfilled', 'Bank Address': 'Unfilled', 'Bank City': 'Unfilled', 'Bank State': 'Unfilled', 'Bank Zip': 'Unfilled', 'Account Name': 'Unfilled', 'Account Number': 'Unfilled', 'ABA Routing Number': 'Unfilled', 'Beneficiary Account Name': 'Unfilled', 'Beneficiary Account Number': 'Unfilled', 'Advisor Phone Number': '', 'Subscriber Letters': 'Unfilled', 'Signature1': ''}
其中'Beneficial Owner Name'字段位于'Type of Subscriber'之后、'Controlling Individual'字段之前。
问题原因
原代码仅遍历了PDF页面的Annots(注释)集合,但部分PDF表单字段是存储在文档根级的AcroForm字典中,而非页面注释里,导致这部分字段被遗漏。
解决方案
修改函数,同时读取AcroForm字段和页面注释字段,确保覆盖所有可能的表单字段:
def read_pdf_form(path_to_pdf): pdf = PdfReader(path_to_pdf) field_values = {} # 读取AcroForm中的标准表单字段 if hasattr(pdf, 'acroform') and pdf.acroform: for field in pdf.acroform.Fields: # 处理字段名:兼容字节/带括号的字符串格式 field_name = field.get('/T') if field_name: if isinstance(field_name, bytes): field_name = field_name.decode('utf-8') elif isinstance(field_name, str) and field_name.startswith('(') and field_name.endswith(')'): field_name = field_name[1:-1] # 处理字段值:解码并格式化 field_value = field.get('/V', '') if isinstance(field_value, bytes): field_value = field_value.decode('utf-8') elif isinstance(field_value, str) and field_value.startswith('(') and field_value.endswith(')'): field_value = field_value[1:-1] field_values[field_name] = field_value or '' # 读取页面注释中的字段,兼容非标准PDF结构 annotations = [ann for page in pdf.pages for ann in page.Annots or []] for ann in annotations: if ann.get('T'): ann_name = ann.T if isinstance(ann_name, bytes): ann_name = ann_name.decode('utf-8') elif isinstance(ann_name, str) and ann_name.startswith('(') and ann_name.endswith(')'): ann_name = ann_name[1:-1] ann_value = ann.V if ann.V else '' if isinstance(ann_value, bytes): ann_value = ann_value.decode('utf-8') elif isinstance(ann_value, str) and ann_value.startswith('(') and ann_value.endswith(')'): ann_value = ann_value[1:-1] # 避免覆盖AcroForm中已有的字段 if ann_name not in field_values: field_values[ann_name] = ann_value print("Extracted field values from PDF:", field_values, "\n") return field_values
修改说明
- 优先读取文档根级的
acroform字段,这是标准PDF表单的官方存储位置 - 兼容字段名和值的多种格式(字节字符串、带括号的PDF原生字符串),确保正确解码
- 保留页面注释字段的读取逻辑,适配非标准格式的旧版PDF
- 合并字段时避免重复覆盖,优先保留AcroForm中的字段值
内容的提问来源于stack exchange,提问作者PaidForThis
相关产品推荐
相关产品推荐

