Вопрос

Следуя этому примеру, я могу перечислить все элементы в файл 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'] должен быть тот элемент, который вам нужен.

Вы можете попробовать распечатать это отдельно или ткнуть в него с помощью help и dir в приглашении Python для получения дополнительной информации о том, как получить нужную строку

Редактировать:

получив копию 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()

Другие советы

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)}

Метод Джехии хорош, если везде искать объект. Я предполагаю (глядя на PDF), что он всегда находится в одном и том же месте (первая страница, в свойстве 'MC0'), и поэтому гораздо более простой метод поиска строки будет выглядеть так:

import pyPdf
pdf = pyPdf.PdfFileReader(open("file.pdf"))
pdf.getPage(0)['/Resources']['/Properties']['/MC0']['/MYOBJECT'].getData()
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top