You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

修改说明

  1. 优先读取文档根级的acroform字段,这是标准PDF表单的官方存储位置
  2. 兼容字段名和值的多种格式(字节字符串、带括号的PDF原生字符串),确保正确解码
  3. 保留页面注释字段的读取逻辑,适配非标准格式的旧版PDF
  4. 合并字段时避免重复覆盖,优先保留AcroForm中的字段值

内容的提问来源于stack exchange,提问作者PaidForThis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 20:57:07