Hvordan trekke ut tekst, lenker og bilder fra PDF-filer ved hjelp av Python

Python er et veldig allsidig språk, og Python-utviklere må ofte jobbe med en rekke filer og få informasjon lagret i dem for behandling. Et populært filformat du garantert vil møte som Python-utvikler, er Portable Document Format populært kjent som PDF

PDF-filer kan inneholde tekst, bilder og lenker. Når du behandler data i et Python-program, kan det hende du trenger å trekke ut dataene som er lagret i et PDF-dokument. I motsetning til datastrukturer som tupler, lister og ordbøker, kan det virke vanskelig å få informasjon lagret i et PDF-dokument.

Heldigvis finnes det en rekke biblioteker som gjør det enkelt å jobbe med PDF-er og trekke ut dataene som er lagret i PDF-filer. For å lære om disse forskjellige bibliotekene, la oss se på hvordan du kan trekke ut tekster, lenker og bilder fra PDF-filer. For å følge med, last ned følgende PDF-fil og lagre den i samme katalog som Python-programfilen.

For å trekke ut tekst fra PDF-filer ved hjelp av Python, skal vi bruke PyPDF2 bibliotek. PyPDF2 er et gratis og åpen kildekode Python-bibliotek som kan brukes til å slå sammen, beskjære og transformere sidene til PDF-filer. Den kan legge til tilpassede data, visningsalternativer og passord til PDF-filer. Men viktigere er at PyPDF2 kan hente tekst fra PDF-filer.

For å bruke PyPDF2 til å trekke ut tekst fra PDF-filer, installer den ved å bruke pip, som er et pakkeinstallasjonsprogram for Python. pip lar deg installere forskjellige Python-pakker på maskinen din:

1. Sjekk om du allerede har pip installert ved å kjøre:

pip --version

Hvis du ikke får tilbake et versjonsnummer, betyr det at pip ikke er installert.

2. For å installere pip, klikk på få pip for å laste ned installasjonsskriptet.

Linken åpner en side med skriptet for å installere pip som vist nedenfor:

Høyreklikk på siden og klikk på Lagre som for å lagre filen. Som standard er navnet på filen get-pip.py

Åpne terminalen og naviger til katalogen med get-pip.py-filen du nettopp lastet ned, og kjør deretter kommandoen:

sudo python3 get-pip.py

Dette bør installere pip som vist nedenfor:

3. Sjekk at pip ble installert vellykket ved å kjøre:

pip --version

Hvis det lykkes, bør du få et versjonsnummer:

Med pip installert kan vi nå begynne å jobbe med PyPDF2.

1. Installer PyPDF2 ved å utføre følgende kommando i terminalen:

pip install PyPDF2

2. Lag en Python-fil og importer PdfReader fra PyPDF2 ved å bruke følgende linje:

from PyPDF2 import PdfReader

PyPDF2-biblioteket tilbyr en rekke klasser for arbeid med PDF-filer. En slik klasse er PdfReader, som blant annet kan brukes til å åpne PDF-filer, lese innholdet og trekke ut tekst fra PDF-filer.

3. For å begynne å jobbe med en PDF-fil må du først åpne filen. For å gjøre dette, lag en forekomst av PdfReader-klassen og send inn PDF-filen du vil jobbe med:

reader = PdfReader('games.pdf')

Linjen ovenfor instansierer PdfReader og forbereder den til å få tilgang til innholdet i PDF-filen du spesifiserer. Forekomsten er lagret i en variabel kalt reader, som må ha tilgang til en rekke metoder og egenskaper tilgjengelig i PdfReader-klassen.

4. For å se om alt fungerer som det skal, skriv ut antall sider i PDF-en du sendte inn ved å bruke følgende kode:

print(len(reader.pages))

Produksjon:

5

5. Siden vår PDF-fil har 5 sider, kan vi få tilgang til hver side som er tilgjengelig i PDF-en. Imidlertid starter tellingen fra 0, akkurat som Pythons indekseringskonvensjon. Derfor vil den første siden i pdf-filen være sidenummer 0. For å hente den første siden i PDF-en, legg til følgende linje i koden din:

page1 = reader.pages[0]

Linjen over henter den første siden i PDF-filen, og lagrer den i en variabel kalt side1.

6. For å trekke ut teksten på den første siden av PDF-filen, legg til følgende linje:

textPage1 = page1.extract_text()

Dette trekker ut teksten på den første siden av PDF-en og lagrer innholdet i en variabel kalt textPage1. Du har dermed tilgang til teksten på første side av PDF-filen gjennom variabelen textPage1.

7. For å bekrefte at teksten ble pakket ut, kan du skrive ut innholdet i variabelen textPage1. Hele koden vår, som også skriver ut teksten på første side av PDF-filen, vises nedenfor:

# 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)

Produksjon:

For å trekke ut lenker fra PDF-filer, går vi til PyMuPDF som er et Python-bibliotek for å trekke ut, analysere, konvertere og manipulere dataene som er lagret i dokumenter som PDF-er. For å bruke PyMuPDF, bør du ha Python 3.8 eller nyere. For å komme i gang:

1. Installer PyMuPDF ved å kjøre følgende linje i terminalen:

pip install PyMuPDF

2. Importer PyMuPDF til Python-filen ved å bruke følgende setning:

import fitz

3. For å få tilgang til PDF-en du vil trekke ut lenker fra, må du først åpne den. For å åpne den, skriv inn følgende linje:

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

4. Etter å ha åpnet PDF-filen, skriv ut antall sider i PDF-en ved å bruke følgende linje:

print(doc.page_count)

Produksjon:

5

4. For å trekke ut lenker fra en side i PDF-filen, må vi laste inn siden vi vil trekke lenker fra. For å laste inn en side, skriv inn følgende linje, der du sender inn sidetallet du vil laste inn i en funksjon kalt load_page()

page = doc.load_page(0)

For å trekke ut lenker fra den første siden sender vi inn 0(null). Tellingen av sider starter fra null akkurat som i datastrukturer som matriser og ordbøker.

5. Trekk ut koblingene fra siden ved å bruke følgende linje:

links = page.get_links()

Alle lenkene på siden du spesifiserte, i vårt tilfelle side 1, vil bli trukket ut og lagret i variabelen kalt lenker

6. For å se innholdet i koblingsvariabelen, skriv den ut slik:

print(links)

Produksjon:

Legg merke til at variabellenkene inneholder en liste over ordbøker med nøkkelverdi-par fra den trykte utskriften. Hver lenke på siden er representert av en ordbok, med den faktiske lenken lagret under nøkkelen «uri»

7. For å få lenkene fra listen over objekter som er lagret under variabelnavn-lenkene, gjenta gjennom listen ved å bruke en for-in-setning og skrive ut de spesifikke koblingene som er lagret under nøkkel-urien. Hele koden som gjør dette er vist nedenfor:

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"])

Produksjon:

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

8. For å gjøre koden vår mer gjenbrukbar, kan vi refaktorere den ved å definere en funksjon for å trekke ut alle lenkene i en PDF og en funksjon for å skrive ut alle koblingene som finnes i en PDF. På denne måten kan du kalle opp funksjonene med hvilken som helst PDF-fil, og du får tilbake alle lenkene i PDF-en. Koden som gjør dette er vist nedenfor:

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)

Produksjon:

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

Fra koden ovenfor mottar funksjonen extract_link() en PDF-fil, itererer gjennom alle sidene i PDF-en, trekker ut alle koblingene og returnerer dem. Resultatet av denne funksjonen er lagret i en variabel som heter all_links

Funksjonen print_all_links() tar inn resultatet av extract_link(), itererer gjennom listen og skriver ut alle de faktiske koblingene som er funnet i PDF-en du sendte inn i extract_link()-funksjonen.

For å trekke ut bilder fra en PDF, kommer vi fortsatt til å bruke PyMuPDF. Slik trekker du ut bilder fra en PDF-fil:

1. Importer PyMuPDF, io og PIL. Python Imaging Library (PIL) gir verktøy som gjør det enkelt å lage og lagre bilder, blant andre funksjoner. io gir klasser for enkel og effektiv håndtering av binære data.

import fitz
from io import BytesIO
from PIL import Image

2. Åpne PDF-filen du vil trekke ut bilder fra:

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

3. Last inn siden du vil trekke ut bilder fra:

page = doc.load_page(0)

4. PyMuPdf identifiserer bilder på en PDF-fil ved hjelp av et kryssreferansenummer(xref), som vanligvis er et heltall. Hvert bilde på en PDF-fil har en unik xref. Derfor, for å trekke ut et bilde fra en PDF, må vi først få xref-nummeret som identifiserer det. For å få xref-nummeret til bildene på en side, bruker vi funksjonen get_images() slik:

image_xref = page.get_images()
print(image_xref)

Produksjon:

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

get_images() returnerer en liste over tupler med informasjon om bildet. Siden vi kun har ett bilde på første side, er det kun en tuppel. Det første elementet i tuppelen representerer xref av bildet på siden. Derfor er xref av bildet på første side 7.

5. For å trekke ut xref-verdien for bildet fra listen over tupler, bruker vi koden nedenfor:

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

Produksjon:

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

6. Siden du nå har xref som identifiserer et bilde på PDF-en, kan du trekke ut bildet ved å bruke extract_image()-funksjonen slik:

img_dictionary = doc.extract_image(xref_value)

Denne funksjonen returnerer imidlertid ikke det faktiske bildet. I stedet returnerer den en ordbok som inneholder de binære bildedataene til bildet og metadata om bildet, blant annet.

7. Fra ordboken som returneres av extract_image()-funksjonen, sjekk filtypen til det utpakkede bildet. Filtypen er lagret under nøkkelen «ext»:

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

Produksjon:

png

8. Trekk ut bildebinærene fra ordboken som er lagret i img_dictionary. Bildebinærene lagres under nøkkelen «bilde»

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

9. Lag et BytesIO-objekt og initialiser det med de binære bildedataene som representerer bildet. Dette lager et fillignende objekt som kan behandles av Python-biblioteker som PIL slik at du kan lagre bildet.

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

10. Åpne og analyser bildedataene som er lagret i BytesIO-objektet kalt image_io ved å bruke PIL-biblioteket. Dette er viktig siden det lar PIL-biblioteket bestemme bildeformatet til bildet du prøver å jobbe med, i dette tilfellet en PNG. Etter å ha oppdaget bildeformatet, oppretter PIL et bildeobjekt som kan manipuleres med PIL-funksjoner og metoder, for eksempel save()-metoden, for å lagre bildet til lokal lagring.

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

11. Angi banen der du vil lagre bildet.

output_path = "image_1.png"

Siden banen ovenfor bare inneholder navnet på filen med filtypen, vil det utpakkede bildet bli lagret i samme katalog som Python-filen som inneholder dette programmet. Bildet vil bli lagret som image_1.png. PNG-utvidelsen er viktig for at den skal matche den opprinnelige utvidelsen av bildet.

12. Lagre bildet og lukk ByteIO-objektet.

# save the image
image.save(output_path)

# Close the BytesIO object 
image_io.close()

Hele koden for å trekke ut et bilde fra en PDF-fil vises nedenfor:

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()

Kjør koden og gå til mappen som inneholder Python-filen; du bør se det utpakkede bildet med navnet image_1.png, som vist nedenfor:

Konklusjon

For å få mer øvelse med å trekke ut lenker, bilder og tekster fra PDF-er, prøv å refaktorisere koden i eksemplene for å gjøre dem mer gjenbrukbare, som vist i koblingseksemplet. På denne måten trenger du bare å sende inn en PDF-fil, og Python-programmet vil trekke ut alle koblingene, bildene eller teksten i hele PDF-en. Lykke til med koding!

Du kan også utforske noen beste PDF-APIer for ethvert forretningsbehov.