【问题标题】:pyPdf for IndirectObject extraction用于 IndirectObject 提取的 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 文件的链接吗?
  • 如果我的回答中的信息没有帮助,正如 Jehiah 所说,一个示例 PDF 文件可以让您轻松地为您提供真正的代码。如果您不想公开发布,请通过电子邮件将其发送至 tony.meyer@gmail.com。

标签: python pdf stream pypdf


【解决方案1】:

pdf.pages 中的每个元素都是一个字典,因此假设它位于第 1 页,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.resolvedObjects[0][n]KeyError: 0。这对我有用:pdf.resolvedObjects[(0,n)]
  • NotImplementedError: unsupported filter /DCTDecode 我收到此错误。
【解决方案2】:

IndirectObject 指的是实际对象(它类似于链接或别名,因此当相同内容出现在多个位置时可以减小 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)}

【讨论】:

    【解决方案3】:

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

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

    【讨论】:

    • 我如何找出过滤器?? ['/Resources']['/Properties']['/MC0']['/MYOBJECT']这些你指的是?
    • 要么打印整个结构,要么使用 iText RUPS 等工具浏览 PDF。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-11
    • 1970-01-01
    相关资源
    最近更新 更多