Dividere e rinominare un PDF in base al contenuto del file

In questo veloce post ti parlo di una di quelle straordinarie, veloci, magiche, automazioni che è possibile realizzare con poche righe di codice in Pyhton.

È qualcosa sullo stile dei task illustrati in “Automate the Boring Stuff with Python“.

L’esigenza è la seguente:
prendere un PDF di più pagine, spezzettarlo e rinominare i singoli file estratti in base al contenuto della singola pagina.

Questo post ha del codice bello e pronto per le nostre esigenze: “Extract PDF Pages and Rename Based on Text in Each Page (Python)”.

Analizziamolo e comprendiamolo per adattarlo alle nostre esigenze.

Il processo

processo dello script di spilt e rinomina PDF in base al contenuto

Il codice

# import the neccessary modules
import os, PyPDF2, re

# function to extract the individual pages from each pdf found
def split_pdf_pages(root_directory, extract_to_folder):
 # traverse down through the root directory to sub-directories
 for root, dirs, files in os.walk(root_directory):
  for filename in files:
   basename, extension = os.path.splitext(filename)
   # if a file is a pdf
   if extension == ".pdf":
    # create a reference to the full filename path
    fullpath = root + "\\" + basename + extension

    # open the pdf in read mode
    opened_pdf = PyPDF2.PdfFileReader(open(fullpath,"rb"))

    # for each page in the pdf
    for i in range(opened_pdf.numPages):
    # write the page to a new pdf
     output = PyPDF2.PdfFileWriter()
     output.addPage(opened_pdf.getPage(i))
     with open(extract_to_folder + "\\" + basename + "-%s.pdf" % i, "wb") as output_pdf:
      output.write(output_pdf)

# function for renaming the single page pdfs based on text in the pdf
def rename_pdfs(extraced_pdf_folder, rename_folder):
 # traverse down through the root directory to sub-directories
 for root, dirs, files in os.walk(extraced_pdf_folder):
  for filename in files:
   basename, extension = os.path.splitext(filename)
   # if a file is a pdf
   if extension == ".pdf":
    # create a reference to the full filename path
    fullpath = root + "\\" + basename + extension

    # open the individual pdf
    pdf_file_obj = open(fullpath, "rb")
    pdf_reader = PyPDF2.PdfFileReader(pdf_file_obj)

    # access the individual page
    page_obj = pdf_reader.getPage(0)
    # extract the the text
    pdf_text = page_obj.extractText()

    # use regex to find information
    for index in re.finditer("THE-DOC-PREFIX-", pdf_text):
     doc_ext = pdf_text[index.end():index.end() + 14]
     doc_num = "THE-DOC-PREFIX-" + doc_ext
     pdf_file_obj.close()
     # rename the pdf based on the information in the pdf
     os.rename(fullpath, rename_folder + "\\" + doc_num + ".pdf")

# parameter variables
root_dir = r"C:\Users\******\Documents\rename_pdf"
extract_to = r"C:\Users\******\Documents\extracted"
rename_to = r"C:\Users\******\Documents\renamed"

# use the two functions
split_pdf_pages(root_dir, extract_to)
rename_pdfs(extract_to,rename_to)

Per prima cosa utilizzeremo tre moduli:

import os, PyPDF2, re
  • os, per ravanare nella cartella dei file;
  • PyPDF2, per eseguire le operazioni di split e lettura su PDF;
  • re, per processare le espressioni regolari di ricerca e acquisizione del contenuto.

Lo script ha due funzioni essenziali:

  1. def split_pdf_pages, che cerca i PDF all’interno della cartella sorgente e splitta le singole pagine nella cartella di split. Questa funzione è costruita in modo che nella cartella di origine si possano caricare più file.
  2. rename_pdfs, che all’interno della cartella di split preleva i singoli PDF e, in base al risultato della ricerca dell’espressione regolare, rinomina i file in una nuova cartella di destinazione finale.

Le cartelle di origine, split/estrazione e rinomina finale sono definibili nelle seguenti variabili:

# parameter variables
root_dir = r"C:\Users\******\Documents\rename_pdf"
extract_to = r"C:\Users\******\Documents\extracted"
rename_to = r"C:\Users\******\Documents\renamed"

La parte, secondo me, interessante da comprendere è quella relativa la ricerca tramite espressione regolare:

  # use regex to find information
    for index in re.finditer("THE-DOC-PREFIX-", pdf_text):
     doc_ext = pdf_text[index.end():index.end() + 14]
     doc_num = "THE-DOC-PREFIX-" + doc_ext
     pdf_file_obj.close()
     # rename the pdf based on the information in the pdf
     os.rename(fullpath, rename_folder + "\\" + doc_num + ".pdf")

Essenzialmente la funzione, in questo punto, all’apertura del ciclo for, va alla ricerca della porzione di testo “THE-DOC-PREFIX-” su file, e preleva i 14 caratteri successivi che ne seguono.

Alcune considerazioni che penso possano tornare utili quando proverai ad applicare lo script al singolo caso reale:

  • l’acquisizione della stringa con cui rinominare il file può essere eseguita anche andando all’indietro, partendo dalla parola chiave ricercata nel PDF. In tal caso:
    doc_ext = pdf_text[index.start() – 14: index.start()]
  • non è detto che i 14 caratteri (o altro numero) acquisiti dalla ricerca siano sempre puliti puliti.
    Con un po’ di lavoro sulla variabile string doc_ext puoi risolvere problemini vari e/o formattare il nome finale in modo più leggibile.

Due esempi relativi l’ultimo punto:

Puoi eliminare i primi 3 caratteri della stringa.
E rimuovere tutti gli spazi.
E rimuovere tutti gli “a capo”:

doc_num = "PREFISSO-A-PIACERE" + doc_ext[3:].replace(" ", "").replace("\n", "")

Oppure… puoi rimuovere una porzione di testo che non ti interessa dalla stringa:

doc_num = re.sub(r'\d+', '', doc_ext).replace("elimina questo testo", "")

Considera che il codice sopra riportato è scritto per Windows.

Se utilizzi lo script su Linux ricorda di modificare, oltre il formato delle variabili di percorso, anche quelle che dichiarano i relativi path.
Esempio:

fullpath = root + "/" + basename + extension

Discussione in tema su Reddit (per risolvere senza l’utilizzo di Python).

Posted in Python.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *