La respuesta por Kindall es muy bueno. Sin embargo, dado que una muestra de código de trabajo fue solicitada más tarde (por soñador) y dado que tenía el mismo problema hoy, me gustaría agregar algunas notas.
estructura en pdf no es uniforme; hay pocas cosas en las que puede confiar, por lo tanto, es muy poco probable que una muestra de código de trabajo funcione para todos.Una muy buena explicación se puede encontrar in this answer.
Según lo explica kindall, lo más probable es que necesite explorar qué pdf está tratando.
así:
import sys
import PyPDF2 as pyPdf
"""Open your pdf"""
pdf = pyPdf.PdfFileReader(open(sys.argv[1], "rb"))
"""Explore the /PageLabels (if it exists)"""
try:
page_label_type = pdf.trailer["/Root"]["/PageLabels"]
print(page_label_type)
except:
print("No /PageLabel object")
"""Select the item that is most likely to contain the information you desire; e.g.
{'/Nums': [0, IndirectObject(42, 0)]}
here, we only have "/Num". """
try:
page_label_type = pdf.trailer["/Root"]["/PageLabels"]["/Nums"]
print(page_label_type)
except:
print("No /PageLabel object")
"""If you see a list, like
[0, IndirectObject(42, 0)]
get the correct item from it"""
try:
page_label_type = pdf.trailer["/Root"]["/PageLabels"]["/Nums"][1]
print(page_label_type)
except:
print("No /PageLabel object")
"""If you then have an indirect object, like
IndirectObject(42, 0)
use getObject()"""
try:
page_label_type = pdf.trailer["/Root"]["/PageLabels"]["/Nums"][1].getObject()
print(page_label_type)
except:
print("No /PageLabel object")
"""Now we have e.g.
{'/S': '/r', '/St': 21}
meaning roman numerals, starting with page 21, i.e. xxi. We can now also obtain the two variables directly."""
try:
page_label_type = pdf.trailer["/Root"]["/PageLabels"]["/Nums"][1].getObject()["/S"]
print(page_label_type)
start_page = pdf.trailer["/Root"]["/PageLabels"]["/Nums"][1].getObject()["/St"]
print(start_page)
except:
print("No /PageLabel object")
- Como se puede ver en el PDF 1.7 especificación ISO (sección correspondiente here) hay un montón de posibilidades de cómo etiquetar páginas. Como un simple ejemplo de trabajo considerar este script que va a al menos trato con decimales (árabe) y con números romanos:
Guión:
import sys
import PyPDF2 as pyPdf
def arabic_to_roman(arabic):
roman = ''
while arabic >= 1000:
roman += 'm'
arabic -= 1000
diffs = [900, 500, 400, 300, 200, 100, 90, 50, 40, 30, 20, 10, 9, 5, 4, 3, 2, 1]
digits = ['cm', 'd', 'cd', 'ccc', 'cc', 'c', 'xc', 'l', 'xl', 'xxx', 'xx', 'x', 'ix', 'v', 'iv', 'iii', 'ii', 'i']
for i in range(len(diffs)):
if arabic >= diffs[i]:
roman += digits[i]
arabic -= diffs[i]
return(roman)
def get_page_labels(pdf):
try:
page_label_type = pdf.trailer["/Root"]["/PageLabels"]["/Nums"][1].getObject()["/S"]
except:
page_label_type = "/D"
try:
page_start = pdf.trailer["/Root"]["/PageLabels"]["/Nums"][1].getObject()["/St"]
except:
page_start = 1
page_count = pdf.getNumPages()
##or, if you feel fancy, do:
#page_count = pdf.trailer["/Root"]["/Pages"]["/Count"]
page_stop = page_start + page_count
if page_label_type == "/D":
page_numbers = list(range(page_start, page_stop))
for i in range(len(page_numbers)):
page_numbers[i] = str(page_numbers[i])
elif page_label_type == '/r':
page_numbers_arabic = range(page_start, page_stop)
page_numbers = []
for i in range(len(page_numbers_arabic)):
page_numbers.append(arabic_to_roman(page_numbers_arabic[i]))
print(page_label_type)
print(page_start)
print(page_count)
print(page_numbers)
pdf = pyPdf.PdfFileReader(open(sys.argv[1], "rb"))
get_page_labels(pdf)
He intentado leer, pero no sirve .......... ¿Puede dar una muestra de código de trabajo? – dreamer