使用PyPDF2获取复选框和单选字段



我的项目涉及从一堆PDF表单文件中读取文本,我正在使用PyPDF2开源库。获取以下文本数据没有问题:

reader = PdfReader("data/test.pdf")
cnt = len(reader.pages)
print("reading pdf (%d pages)" % cnt)
page = reader.pages[cnt-1]
lines = page.extract_text().splitlines()
print("%d lines extracted..." % len(lines))

但是,此文本不包含单选框和复选框的选中状态。我只得到普通文本(例如Yes NoCheck-1 Check-2 Check-3(,而不是这些值。

我还尝试了文档中描述的reader.get_fields()reader.get_form_text_fields()方法,但它们返回空值。我还试着通过注释来阅读它,但在页面上找不到"/Annots"。当我在notepad++中打开PDF以查看其元数据时,我得到的是:

%PDF-1.4
%²³´µ
%Generated by ExpertPdf v9.2.2

在我看来,这些复选框不是PDF中常用的表单字段,而是类似于HTML元素。有没有任何方法可以使用python提取这些字段?

最后,我还尝试了pdfminer.six,这是另一个流行的python pdf库,结果相同。

您的PDF似乎包含XFA表单,而pdfminer.six库不支持这些表单。

您可以使用此工具提取XFA表单。

如果您的PDF不包含XFA表单,您可以使用pdfminer.six-docs 中的以下片段提取表单字段和值数据

from pdfminer.pdfparser import PDFParser
from pdfminer.pdfdocument import PDFDocument
from pdfminer.pdftypes import resolve1
from pdfminer.psparser import PSLiteral, PSKeyword
from pdfminer.utils import decode_text

data = {}

def decode_value(value):
# decode PSLiteral, PSKeyword
if isinstance(value, (PSLiteral, PSKeyword)):
value = value.name
# decode bytes
if isinstance(value, bytes):
value = decode_text(value)
return value

with open(file_path, 'rb') as fp:
parser = PDFParser(fp)
doc = PDFDocument(parser)
res = resolve1(doc.catalog)
if 'AcroForm' not in res:
raise ValueError("No AcroForm Found")
fields = resolve1(doc.catalog['AcroForm'])['Fields']  # may need further resolving
for f in fields:
field = resolve1(f)
name, values = field.get('T'), field.get('V')
# decode name
name = decode_text(name)
# resolve indirect obj
values = resolve1(values)
# decode value(s)
if isinstance(values, list):
values = [decode_value(v) for v in values]
else:
values = decode_value(values)
data.update({name: values})
print(name, values)

如果上面的代码抛出No AcroForm found错误,则意味着您的PDF很可能包含XFA表单。

最新更新