pyPdf لاستخراج IndirectObject
سؤال
وبعد هذا المثال، لا أستطيع سرد جميع العناصر في ملف قوات الدفاع الشعبي
import pyPdf
pdf = pyPdf.PdfFileReader(open("pdffile.pdf"))
list(pdf.pages) # Process all the objects.
print pdf.resolvedObjects
والآن، ولست بحاجة لاستخراج كائن غير قياسي من ملف قوات الدفاع الشعبي.
وجوه بلدي هو اسمه MYOBJECT واحدة وهي سلسلة.
وقطعة المطبوعة من قبل البرنامج النصي الثعبان أن concernes لي هو:
{'/MYOBJECT': IndirectObject(584, 0)}
وملف قوات الدفاع الشعبي هو هذا:
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
هو القاموس، وذلك على افتراض انها على الصفحة 1، وينبغي أن يكون pdf.pages[0]['/MYOBJECT']
العنصر الذي تريد.
ويمكنك محاولة طباعة هذا بشكل فردي أو كزة في ذلك مع help
وdir
في موجه الثعبان لمعرفة المزيد عن كيفية الحصول على السلسلة التي تريد
وتحرير:
وبعد حصوله على نسخة من قوات الدفاع الشعبي، وجدت الكائن في 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 تعطيك الكائن الفعلي.
إذا كان الكائن كائن النص، ثم مجرد القيام شارع () أو يونيكود () على كائن يجب أن تحصل على البيانات داخل منه.
وبدلا من ذلك، ومخازن 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()