English 中文(简体)
pyPdf用于间接对象提取
原标题:
  • 时间:2009-01-12 18:31:52
  •  标签:

按照这个例子,我可以将所有元素列入一个PDF文件。

import pyPdf
pdf = pyPdf.PdfFileReader(open("pdffile.pdf"))
list(pdf.pages) # Process all the objects.
print pdf.resolvedObjects

现在,我需要从PDF文件中提取一个非标准对象。

我的对象是名为MYOBJECT的字符串。

让我关注的Python脚本打印出来的部分是:

{ /MYOBJECT : IndirectObject(584, 0)}

这个 PDF 文件是这样的:

558 0 obj
<</Contents 583 0 R/CropBox[0 0 595.22 842]/MediaBox[0 0 595.22 842]/Parent 29 0 R/Resources
  <</ColorSpace <</CS0 563 0 R>>
    /ExtGState <</GS0 568 0 R>>
    /Font<</TT0 559 0 R/TT1 560 0 R/TT2 561 0 R/TT3 562 0 R>>
    /ProcSet[/PDF/Text/ImageC]
    /Properties<</MC0<</MYOBJECT 584 0 R>>/MC1<</SubKey 582 0 R>> >>
    /XObject<</Im0 578 0 R>>>>
  /Rotate 0/StructParents 0/Type/Page>>
endobj
...
...
...
584 0 obj
<</Length 8>>stream

1_22_4_1     --->>>>  this is the string I need to extract from the object

endstream
endobj

我怎样才能跟踪 584 的值以便引用我的字符串(当然是在pyPdf中)?

最佳回答

pdf.pages 中的每个元素都是一个字典,所以假设它在第一页,pdf.pages[0]['/MYOBJECT'] 应该是您想要的元素。

你可以尝试逐个打印或在python提示符中使用helpdir来了解如何获取你想要的字符串。

编辑:

收到PDF副本后,我在pdf.resolvedObjects[0][558][ /Resources ][ /Properties ][ /MC0 ][ /MYOBJECT ]找到了该对象,可以通过getData()方法检索该值。

以下函数通过递归查找所需的键,提供了一种更通用的解决方法。

import types
import pyPdf
pdf = pyPdf.PdfFileReader(open( file.pdf ))
pages = list(pdf.pages)

def findInDict(needle,haystack):
    for key in haystack.keys():
        try:
            value = haystack[key]
        except:
            continue
        if key == needle:
            return value
        if type(value) == types.DictType or isinstance(value,pyPdf.generic.DictionaryObject):  
            x = findInDict(needle,value)
            if x is not None:
                return x

answer = findInDict( /MYOBJECT ,pdf.resolvedObjects).getData()
问题回答

一个间接对象指的是实际对象(它类似于一个链接或别名,这样在同一内容出现在多个地方时可以减少PDF的总大小)。getObject方法将提供实际对象。

如果对象是文本对象,则只需在对象上执行str()或unicode()即可获取其中的数据。

或者,pyPdf 将对象存储在 resolvedObjects 属性中。例如,包含此对象的 PDF:

13 0 obj
<< /Type /Catalog /Pages 3 0 R >>
endobj

可以使用这个阅读:

>>> import pyPdf
>>> pdf = pyPdf.PdfFileReader(open("pdffile.pdf"))
>>> pages = list(pdf.pages)
>>> pdf.resolvedObjects
{0: {2: { /Parent : IndirectObject(3, 0),  /Contents : IndirectObject(4, 0),  /Type :  /Page ,  /Resources : IndirectObject(6, 0),  /MediaBox : [0, 0, 595.2756, 841.8898]}, 3: { /Kids : [IndirectObject(2, 0)],  /Count : 1,  /Type :  /Pages ,  /MediaBox : [0, 0, 595.2756, 841.8898]}, 4: { /Filter :  /FlateDecode }, 5: 147, 6: { /ColorSpace : { /Cs1 : IndirectObject(7, 0)},  /ExtGState : { /Gs2 : IndirectObject(9, 0),  /Gs1 : IndirectObject(10, 0)},  /ProcSet : [ /PDF ,  /Text ],  /Font : { /F1.0 : IndirectObject(8, 0)}}, 13: { /Type :  /Catalog ,  /Pages : IndirectObject(3, 0)}}}
>>> pdf.resolvedObjects[0][13]
{ /Type :  /Catalog ,  /Pages : IndirectObject(3, 0)}

如果要在所有地方寻找物体,Jehiah的方法很好。我的猜测(查看PDF),它总是在同一个地方(第一页,在MC0属性中),因此找到该字符串的更简单的方法将是:

import pyPdf
pdf = pyPdf.PdfFileReader(open("file.pdf"))
pdf.getPage(0)[ /Resources ][ /Properties ][ /MC0 ][ /MYOBJECT ].getData()




相关问题
热门标签