【问题标题】:PDF File to Dict Returns Weird CharactersPDF 文件到字典返回奇怪的字符
【发布时间】:2020-01-24 02:03:34
【问题描述】:

我正在尝试创建一个程序,该程序利用 pdfminer 读取 DnD 字符表(可填写 PDF)并将填写内容放入字典中。在编辑 PDF 并再次运行程序后,我在打印字典项时得到了一个奇怪的字符序列。代码:

from pdfminer.pdfparser import PDFParser
from pdfminer.pdfdocument import PDFDocument
from pdfminer.pdftypes import resolve1
import collections

filename = "Edited_CS.pdf"
fp = open(filename, 'rb')
my_dict = {}

parser = PDFParser(fp)
doc = PDFDocument(parser)
fields = resolve1(doc.catalog['AcroForm'])['Fields']

# Checks if PDF file is blank
if isinstance(fields, collections.abc.Sequence) is False:
    print("This Character Sheet is blank. Please submit a filled Character Sheet!")

else:
    for i in fields:
        field = resolve1(i)
        name, value = field.get('T'), field.get('V')
        if value is None or str(value)[2:-1] == "":
            value = "b'None'"
        my_dict[str(name)[2:-1]] = str(value)[2:-1]

    for g in list(my_dict.items()):
        print(g)

未经编辑的 PDF 文件的输出:

('ClassLevel', 'Assassin 1')
('Background', 'Lone Survivor')
('PlayerName', 'None')
('CharacterName', 'Tumas Mitshil')
('Race ', 'Human')
etc...

编辑时的输出(我在PDF中完全更改了ClassLevel等):

('ClassLevel', '\\xfe\\xff\\x00C\\x00l\\x00a\\x00s\\x00s\\x00L\\x00e\\x00v\\x00e\\x00l')
('Background', '\\xfe\\xff\\x00B\\x00a\\x00c\\x00k\\x00g\\x00r\\x00o\\x00u\\x00n\\x00d\\x00r')
('PlayerName', '\\xfe\\xff\\x00P\\x00l\\x00a\\x00y\\x00e\\x00r\\x00N\\x00a\\x00m\\x00e')
('CharacterName', '\\xfe\\xff\\x00T\\x00h\\x00o\\x00m\\x00a\\x00s')
('Race ', '\\xfe\\xff\\x00R\\x00a\\x00c\\x00e')
('Alignment', '\\xfe\\xff\\x00A\\x00l\\x00i\\x00g\\x00n\\x00m\\x00e\\x00n\\x00t')
etc...

我知道这是某种编码,一些 Google 搜索让我相信它是 UTF-8 编码,所以我尝试在打开文件时解码 PDF:

fp = open(filename, 'rb').read().decode('utf-8')

不幸的是,我遇到了一个错误:

Traceback (most recent call last):
  File "main.py", line 16, in <module>
    fp = open(filename, 'rb').read().decode('utf-8')
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xe2 in position 10: invalid continuation byte

当我第一次制作 PDF 时,我使用的是 Adob​​e Acrobat。但是,我使用 Microsoft Edge 编辑文件,这导致了我面临的问题。以下是文件:

Original File Edited File

有什么方法可以正确解码吗?有没有办法对编辑后的 ​​pdf 进行编码,以便可以毫无问题地将其加载到 python 中?如果这是编码的,是否还有其他形式的编码,我将如何解码?

任何帮助将不胜感激。

【问题讨论】:

  • 它是带有前导 BOM 的 UTF-16。
  • 正如@mkl 所说,该字段的值是以字节顺序标记(en.wikipedia.org/wiki/Byte_order_mark)开头的unicode字符串。如果你使用value[2:].decode(),你可以看到你想要的文字,与\x00交织在一起。
  • 如果我恢复使用以前的方法,我一定会尝试一下 :)

标签: python python-3.x pdf pdfminer


【解决方案1】:

您可以通过使用 Adob​​e Acrobat Reader DC 编辑表单域来解决此问题。我已经使用它编辑了Edited_CS.pdf 的表单字段,并且 pdfminer.six 返回了预期的输出。

可能是 Microsoft Edge 导致了此问题。

【讨论】:

  • 非常正确,但我希望它可以接受从任何应用程序保存的任何 PDF,因此我需要正确解码它。但是,我能够解决我的问题。
【解决方案2】:

经过一番挖掘,我找到了更好的解决方案。我没有使用 pdfminer 打开 PDF,而是使用了 PyPDF2。不知何故,无论编码如何,它都可以读取任何 PDF,并且它具有可以自动将可填充空格转换为适当字典的功能。结果是更精细、更简洁的代码:

from PyPDF2 import PdfFileReader

infile = "Edited_CS.pdf"
pdf_reader = PdfFileReader(open(infile, "rb"))

dictionary = pdf_reader.getFormTextFields()

for g in list(dictionary.items()):
    print(g)

无论如何,感谢您的所有回答! :)

【讨论】:

  • 我很好奇 PyPDF2 与 pdfminer 有何不同!我在 pdfminer github 上创建了一个 issue 来解决这个问题。
猜你喜欢
  • 2019-03-22
  • 1970-01-01
  • 1970-01-01
  • 2019-07-05
  • 2017-07-04
  • 2018-03-11
  • 2019-07-27
  • 2014-02-28
  • 1970-01-01
相关资源
最近更新 更多