Kleines Update zu @darrell Klasse zu können UTF-8 Umrisse analysieren, die ich als Antwort posten, weil Kommentar wäre schwer zu lesen.
Problem ist in pyPdf.pdf.Destination.title
, die in zwei Geschmacksrichtungen zurückgeführt werden kann:
pyPdf.generic.TextStringObject
pyPdf.generic.ByteStringObject
so dass die Ausgabe von _setup_outline_page_ids()
Funktion gibt auch zwei unterschiedliche Typen für title
Objekt, das ausfällt mit UnicodeDecodeError
, wenn der Gliederungstitel nichts als ASCII enthält.
Ich habe diesen Code, um das Problem zu lösen:
if isinstance(title, pyPdf.generic.TextStringObject):
title = title.encode('utf-8')
der ganzen Klasse:
class PdfOutline(pyPdf.PdfFileReader):
def getDestinationPageNumbers(self):
def _setup_outline_page_ids(outline, _result=None):
if _result is None:
_result = {}
for obj in outline:
if isinstance(obj, pyPdf.pdf.Destination):
_result[(id(obj), obj.title)] = obj.page.idnum
elif isinstance(obj, list):
_setup_outline_page_ids(obj, _result)
return _result
def _setup_page_id_to_num(pages=None, _result=None, _num_pages=None):
if _result is None:
_result = {}
if pages is None:
_num_pages = []
pages = self.trailer["/Root"].getObject()["/Pages"].getObject()
t = pages["/Type"]
if t == "/Pages":
for page in pages["/Kids"]:
_result[page.idnum] = len(_num_pages)
_setup_page_id_to_num(page.getObject(), _result, _num_pages)
elif t == "/Page":
_num_pages.append(1)
return _result
outline_page_ids = _setup_outline_page_ids(self.getOutlines())
page_id_to_page_numbers = _setup_page_id_to_num()
result = {}
for (_, title), page_idnum in outline_page_ids.iteritems():
if isinstance(title, pyPdf.generic.TextStringObject):
title = title.encode('utf-8')
result[title] = page_id_to_page_numbers.get(page_idnum, '???')
return result