我的项目涉及从一堆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 No
或Check-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表单。