Come estrarre testo, collegamenti e immagini da file PDF utilizzando Python

Python è un linguaggio molto versatile e gli sviluppatori Python spesso devono lavorare con una varietà di file e ottenere informazioni archiviate in essi per l’elaborazione. Un formato di file popolare che incontrerai sicuramente come sviluppatore Python è il formato di documento portatile popolarmente noto come PDF

I file PDF possono contenere testo, immagini e collegamenti. Quando elabori i dati in un programma Python, potresti trovarti a dover estrarre i dati archiviati in un documento PDF. A differenza delle strutture dati come tuple, elenchi e dizionari, ottenere informazioni archiviate in un documento PDF potrebbe sembrare una cosa difficile da fare.

Fortunatamente, esistono numerose librerie che semplificano il lavoro con i PDF ed estraggono i dati archiviati nei file PDF. Per conoscere queste diverse librerie, vediamo come estrarre testi, collegamenti e immagini dai file PDF. Per proseguire, scarica il seguente file PDF e salvalo nella stessa directory del file del programma Python.

Per estrarre testo da file PDF utilizzando Python, utilizzeremo il file PyPDF2 biblioteca. PyPDF2 è una libreria Python gratuita e open source che può essere utilizzata per unire, ritagliare e trasformare le pagine dei file PDF. Può aggiungere dati personalizzati, opzioni di visualizzazione e password ai file PDF. È importante sottolineare, tuttavia, che PyPDF2 può recuperare testo da file PDF.

Per utilizzare PyPDF2 per estrarre testo da file PDF, installalo utilizzando pip, che è un programma di installazione di pacchetti per Python. pip ti consente di installare diversi pacchetti Python sul tuo computer:

1. Controlla se hai già installato pip eseguendo:

pip --version

Se non ricevi il numero di versione, significa che pip non è installato.

2. Per installare pip, fare clic su ottieni pip per scaricare il relativo script di installazione.

Il collegamento apre una pagina con lo script per installare pip come mostrato di seguito:

Fare clic con il tasto destro sulla pagina e fare clic su Salva con nome per salvare il file. Per impostazione predefinita, il nome del file è get-pip.py

Apri il terminale e vai alla directory con il file get-pip.py appena scaricato, quindi esegui il comando:

sudo python3 get-pip.py

Questo dovrebbe installare pip come mostrato di seguito:

3. Verifica che pip sia stato installato correttamente eseguendo:

pip --version

In caso di successo, dovresti ottenere un numero di versione:

Con pip installato, ora possiamo iniziare a lavorare con PyPDF2.

1. Installa PyPDF2 eseguendo il seguente comando nel terminale:

pip install PyPDF2

2. Crea un file Python e importa PdfReader da PyPDF2 utilizzando la seguente riga:

from PyPDF2 import PdfReader

La libreria PyPDF2 fornisce una varietà di classi per lavorare con i file PDF. Una di queste classi è PdfReader, che può essere utilizzata per aprire file PDF, leggere il contenuto ed estrarre testo da file PDF, tra le altre cose.

3. Per iniziare a lavorare con un file PDF devi prima aprire il file. Per fare ciò, crea un’istanza della classe PdfReader e passa il file PDF con cui vuoi lavorare:

reader = PdfReader('games.pdf')

La riga sopra crea un’istanza di PdfReader e lo prepara per accedere al contenuto del file PDF specificato. L’istanza è memorizzata in una variabile chiamata reader, che dovrà accedere a una varietà di metodi e proprietà disponibili nella classe PdfReader.

4. Per vedere se tutto funziona correttamente, stampa il numero di pagine del PDF che hai inserito utilizzando il seguente codice:

print(len(reader.pages))

Produzione:

5

5. Poiché il nostro file PDF ha 5 pagine, possiamo accedere a ciascuna pagina disponibile nel PDF. Tuttavia, il conteggio inizia da 0, proprio come la convenzione di indicizzazione di Python. Pertanto, la prima pagina del file pdf sarà la pagina numero 0. Per recuperare la prima pagina del PDF, aggiungi la seguente riga al tuo codice:

page1 = reader.pages[0]

La riga sopra recupera la prima pagina nel file PDF e la memorizza in una variabile denominata page1.

6. Per estrarre il testo sulla prima pagina del file PDF, aggiungi la seguente riga:

textPage1 = page1.extract_text()

Questo estrae il testo sulla prima pagina del PDF e memorizza il contenuto in una variabile denominata textPage1. Hai così accesso al testo della prima pagina del file PDF attraverso la variabile textPage1.

7. Per confermare che il testo è stato estratto correttamente, è possibile stampare il contenuto della variabile textPage1. Il nostro intero codice, che stampa anche il testo sulla prima pagina del file PDF, è mostrato di seguito:

# import the PdfReader class from PyPDF2
from PyPDF2 import PdfReader

# create an instance of the PdfReader class
reader = PdfReader('games.pdf')

# get the number of pages available in the pdf file
print(len(reader.pages))

# access the first page in the pdf
page1 = reader.pages[0]

# extract the text in page 1 of the pdf file
textPage1 = page1.extract_text()

# print out the extracted text
print(textPage1)

Produzione:

Per estrarre collegamenti da file PDF, utilizzeremo PyMuPDF, una libreria Python per estrarre, analizzare, convertire e manipolare i dati archiviati in documenti come PDF. Per utilizzare PyMuPDF, dovresti avere Python 3.8 o successivo. Per iniziare:

1. Installa PyMuPDF eseguendo la seguente riga nel terminale:

pip install PyMuPDF

2. Importa PyMuPDF nel tuo file Python utilizzando la seguente istruzione:

import fitz

3. Per accedere al PDF da cui desideri estrarre i collegamenti, devi prima aprirlo. Per aprirlo, inserire la seguente riga:

doc = fitz.open("games.pdf")

4. Dopo aver aperto il file PDF, stampa il numero di pagine del PDF utilizzando la seguente riga:

print(doc.page_count)

Produzione:

5

4. Per estrarre i collegamenti da una pagina nel file PDF, dobbiamo caricare la pagina da cui vogliamo estrarre i collegamenti. Per caricare una pagina, inserisci la riga seguente, dove passi il numero di pagina che desideri caricare in una funzione chiamata load_page()

page = doc.load_page(0)

Per estrarre i collegamenti dalla prima pagina, passiamo 0 (zero). Il conteggio delle pagine inizia da zero proprio come nelle strutture dati come array e dizionari.

5. Estrai i collegamenti dalla pagina utilizzando la seguente riga:

links = page.get_links()

Tutti i collegamenti nella pagina specificata, nel nostro caso, la pagina 1, verranno estratti e archiviati nella variabile denominata collegamenti

6. Per vedere il contenuto della variabile links, stampalo in questo modo:

print(links)

Produzione:

Dall’output stampato, nota che i collegamenti variabili contengono un elenco di dizionari con coppie chiave-valore. Ogni collegamento sulla pagina è rappresentato da un dizionario, con il collegamento effettivo memorizzato sotto la chiave “uri“

7. Per ottenere i collegamenti dall’elenco di oggetti memorizzati sotto il nome della variabile links, scorrere l’elenco utilizzando un’istruzione for in e stampare i collegamenti specifici memorizzati sotto la chiave uri. L’intero codice che fa ciò è mostrato di seguito:

import fitz

# Open the PDF file
doc = fitz.open("games.pdf")

# Print out the number of pages
print(doc.page_count)

# load the first page from the PDF
page = doc.load_page(0)

# extract all links from the page and store it under - links
links = page.get_links()

# print the links object
#print(links) 

# print the actual links stored under the key "uri"
for obj in links:
  print(obj["uri"])

Produzione:

5
https://www.statista.com/statistics/1292243/software-developers-average-age-when-first-coding/
https://sparkian.com/
https://www.codemonkey.com/

8. Per rendere il nostro codice più riutilizzabile, possiamo rifattarlo definendo una funzione per estrarre tutti i collegamenti in un PDF e una funzione per stampare tutti i collegamenti trovati in un PDF. In questo modo, puoi chiamare le funzioni con qualsiasi PDF e recupererai tutti i collegamenti nel PDF. Il codice che fa ciò è mostrato di seguito:

import fitz

# Extract all the links in a PDF document
def extract_link(path_to_pdf):
  links = []
  doc = fitz.open(path_to_pdf)

  for page_num in range(doc.page_count):
    page = doc.load_page(page_num)
    page_links = page.get_links()
    links.extend(page_links)
  return links

# print out all the links returned from the PDF document
def print_all_links(links):
  for link in links:
    print(link["uri"])

# Call the function to extract all the links in a pdf
# all the return links are stored under all_links
all_links = extract_link("games.pdf")

# call the function to print all links in the PDF
print_all_links(all_links)

Produzione:

https://www.statista.com/statistics/1292243/software-developers-average-age-when-first-coding/
https://sparkian.com/
https://www.codemonkey.com/
https://scratch.mit.edu/
https://www.tynker.com/
https://codecombat.com/
https://lightbot.com/
https://sparkian.com

Dal codice sopra, la funzione extract_link() riceve un file PDF, scorre tutte le pagine del PDF, estrae tutti i collegamenti e li restituisce. Il risultato di questa funzione è memorizzato in una variabile denominata all_links

La funzione print_all_links() accetta il risultato di extract_link(), scorre l’elenco e stampa tutti i collegamenti effettivi trovati nel PDF passato alla funzione extract_link().

Per estrarre immagini da un PDF, utilizzeremo comunque PyMuPDF. Per estrarre immagini da un file PDF:

1. Importa PyMuPDF, io e PIL. Python Imaging Library (PIL) fornisce strumenti che semplificano la creazione e il salvataggio di immagini, tra le altre funzioni. io fornisce classi per la gestione semplice ed efficiente dei dati binari.

import fitz
from io import BytesIO
from PIL import Image

2. Apri il file PDF da cui desideri estrarre le immagini:

doc = fitz.open("games.pdf")

3. Carica la pagina da cui vuoi estrarre le immagini:

page = doc.load_page(0)

4. PyMuPdf identifica le immagini su un file PDF utilizzando un numero di riferimento incrociato (xref), che solitamente è un numero intero. Ogni immagine su un file PDF ha un xrif univoco. Pertanto, per estrarre un’immagine da un PDF, dobbiamo prima ottenere il numero xrif che la identifica. Per ottenere il numero xrif delle immagini su una pagina, utilizziamo la funzione get_images() in questo modo:

image_xref = page.get_images()
print(image_xref)

Produzione:

[(7, 0, 699, 407, 8, 'DeviceRGB', '', 'X7', 'FlateDecode')]

get_images() restituisce un elenco di tuple con informazioni sull’immagine. Dato che abbiamo solo un’immagine sulla prima pagina, c’è solo una tupla. Il primo elemento nella tupla rappresenta l’xrif dell’immagine sulla pagina. Pertanto, l’xrif dell’immagine sulla prima pagina è 7.

5. Per estrarre il valore xref dell’immagine dall’elenco delle tuple, utilizziamo il codice seguente:

# get xref value of the image
xref_value = image_xref[0][0]
print(xref_value)

Produzione:

[(7, 0, 699, 407, 8, 'DeviceRGB', '', 'X7', 'FlateDecode')]
7

6. Dato che ora hai l’xrif che identifica un’immagine sul PDF, puoi estrarre l’immagine utilizzando la funzione extract_image() in questo modo:

img_dictionary = doc.extract_image(xref_value)

Questa funzione, tuttavia, non restituisce l’immagine reale. Restituisce invece un dizionario contenente, tra le altre cose, i dati binari dell’immagine e i metadati sull’immagine.

7. Dal dizionario restituito dalla funzione extract_image(), verificare l’estensione del file dell’immagine estratta. L’estensione del file è memorizzata sotto la chiave “ext“:

# get file extenstion
img_extension = img_dictionary["ext"]
print(img_extension)

Produzione:

png

8. Estrai i file binari dell’immagine dal dizionario memorizzato in img_dictionary. I file binari dell’immagine sono memorizzati nella chiave “immagine”

# get the actual image binary data
img_binary = img_dictionary["image"]

9. Creare un oggetto BytesIO e inizializzarlo con i dati dell’immagine binaria che rappresenta l’immagine. Questo crea un oggetto simile a un file che può essere elaborato dalle librerie Python come PIL in modo da poter salvare l’immagine.

# create a BytesIO object to work with the image bytes
image_io = BytesIO(img_binary)

10. Aprire e analizzare i dati dell’immagine archiviati nell’oggetto BytesIO denominato image_io utilizzando la libreria PIL. Questo è importante in quanto consente alla libreria PIL di determinare il formato dell’immagine con cui stai tentando di lavorare, in questo caso un PNG. Dopo aver rilevato il formato dell’immagine, PIL crea un oggetto immagine che può essere manipolato con funzioni e metodi PIL, come il metodo save(), per salvare l’immagine nella memoria locale.

# open the image using Pillow
image = Image.open(image_io)

11. Specificare il percorso in cui si desidera salvare l’immagine.

output_path = "image_1.png"

Poiché il percorso sopra contiene solo il nome del file con la sua estensione, l’immagine estratta verrà salvata nella stessa directory del file Python contenente questo programma. L’immagine verrà salvata come image_1.png. L’estensione PNG è importante affinché corrisponda all’estensione originale dell’immagine.

12. Salvare l’immagine e chiudere l’oggetto ByteIO.

# save the image
image.save(output_path)

# Close the BytesIO object 
image_io.close()

L’intero codice per estrarre un’immagine da un file PDF è mostrato di seguito:

import fitz
from io import BytesIO
from PIL import Image

doc = fitz.open("games.pdf")
page = doc.load_page(0)

# get a cross reference(xref) to the image
image_xref = page.get_images()

# get the actual xref value of the image
xref_value = image_xref[0][0]

# extract the image
img_dictionary = doc.extract_image(xref_value)

# get file extenstion
img_extension = img_dictionary["ext"]

# get the actual image binary data
img_binary = img_dictionary["image"]

# create a BytesIO object to work with the image bytes
image_io = BytesIO(img_binary)

# open the image using PIL library 
image = Image.open(image_io)

#specify the path where you want to save the image
output_path = "image_1.png"

# save the image
image.save(output_path)

# Close the BytesIO object 
image_io.close()

Esegui il codice e vai alla cartella contenente il tuo file Python; dovresti vedere l’immagine estratta denominata image_1.png, come mostrato di seguito:

Conclusione

Per fare più pratica con l’estrazione di collegamenti, immagini e testo dai PDF, prova a rifattorizzare il codice negli esempi per renderli più riutilizzabili, come mostrato nell’esempio dei collegamenti. In questo modo, dovrai solo passare un file PDF e il tuo programma Python estrarrà tutti i collegamenti, le immagini o il testo dell’intero PDF. Buona codifica!

Puoi anche esplorare alcune delle migliori API PDF per ogni esigenza aziendale.