3

我正在尝试使用 PDFrw 阅读示例 PDF。PDFHello Matthew在坐标的左下角包含短语(100, 100)。当我尝试输出文本时(如果可以的话?)我得到一个数据流。我似乎无法弄清楚如何将其作为文本获取。

>>> import pdfrw

>>> file_object = pdfrw.PdfReader("Hello.pdf")
>>> file_object
{'/ID': ['<f643bc0910dfb67725d53e11054f4609>', '<f643bc0910dfb67725d53e11054f4609>'], '/Info': (5, 0), '/Root': {'/Outl
ines': (8, 0), '/PageMode': '/UseNone', '/Pages': {'/Count': '1', '/Kids': [{'/Contents': (7, 0), '/MediaBox': ['0', '0
', '595.2756', '841.8898'], '/Parent': {...}, '/Resources': {'/Font': (1, 0), '/ProcSet': ['/PDF', '/Text', '/ImageB',
'/ImageC', '/ImageI']}, '/Rotate': '0', '/Trans': {}, '/Type': '/Page'}], '/Type': '/Pages'}, '/Type': '/Catalog'}, '/S
ize': '9'}

>>> file_object.pages[0]
{'/Contents': (7, 0), '/MediaBox': ['0', '0', '595.2756', '841.8898'], '/Parent': {'/Count': '1', '/Kids': [{...}], '/T
ype': '/Pages'}, '/Resources': {'/Font': (1, 0), '/ProcSet': ['/PDF', '/Text', '/ImageB', '/ImageC', '/ImageI']}, '/Rot
ate': '0', '/Trans': {}, '/Type': '/Page'}

>>> file_object.pages[0].keys()
['/Contents', '/MediaBox', '/Parent', '/Resources', '/Rotate', '/Trans', '/Type']

>>> file_object.pages[0].Contents
{'/Filter': ['/ASCII85Decode', '/FlateDecode'], '/Length': '102'}

>>> file_object.pages[0].Contents.stream
'GapQh0E=F,0U\\H3T\\pNYT^QKk?tc>IP,;W#U1^23ihPEM_?CW4KISi90EC-p>QkRte=<%V"lI7]P)Rn29neZ[Kb,htEWn&q7Q2"V~>'
4

2 回答 2

4

该流被压缩。您可以通过字典 /Filter 参数来判断。

不幸的是,pdfrw (还没有?)知道如何使用这种类型的过滤器进行解压缩。如果你先通过 pdftk 之类的东西运行你的 pdf 文件来解压它,你可能会看到一些更合理的东西。

免责声明:我是 pdfrw 的主要作者。

但...

即便如此,尤其是对于非 ASCII 字体,PDF 中的字符到字形映射很复杂,因此您不会总是看到看起来合理的东西。

如果您真的想深入检查文本 PDF 文件,pdfminer 可能更有用—— pdfrw 还没有真正发展出能够很好地做到这一点的工具。

于 2017-03-30T19:43:05.610 回答
0

如果您的过滤器只有 /Flatedecode 或者您可以找到一个 ASCII85Decode 过滤器首先运行(它们必须按顺序运行)。我一直在使用 pdfrw.uncompress.uncompress(page.Contents) 来解码 /Flatedecode 流(与 PdfReader.uncompress() 不同,该方法不将流传递给处理函数,它提供了所有的间接对象) .

>>> pdf = pdfrw.PdfReader('foo.pdf')
>>> pages = pdf.Root.Pages.Kids
>>> p1 = pages[0]
>>> p1.Contents
{'/Filter': '/FlateDecode', '/Length': '13679'}
>>> p1.Contents.stream[:30]
'x\x9cÕ}Ý\x92æ¶\x91å½"ô\x0eu5Q߬ëk\x02üßP8BRwË'
>>> pdfrw.uncompress.uncompress([p1.Contents]) # Contents object/s in a list.
True # it returns True even if the stream is not decoded.
>>> p1.Contents.stream[:30]
'/Artifact <</Attached [/Top]/T' # ready for parsing

然后搜索以“TJ”或“Tj”结尾的行,并从这些行中获取圆括号内的任何值......你就有了你的文本。

如果您需要文本的位置信息,请查找 BT 和 ET 之间的行块。然后检查行尾,如果你有 Tm 它应该是一个包含 6 个值的数组 [1,0,0,1,x,y] 最后两个数字给你文本起始位置的左下角。

于 2019-01-31T10:48:31.893 回答