
Python är ett mycket mångsidigt språk, och Python-utvecklare måste ofta arbeta med en mängd olika filer och få information lagrad i dem för bearbetning. Ett populärt filformat du kommer att stöta på som Python-utvecklare är Portable Document Format, populärt känt som PDF
PDF-filer kan innehålla text, bilder och länkar. När du bearbetar data i ett Python-program kan du behöva extrahera data som lagras i ett PDF-dokument. Till skillnad från datastrukturer som tupler, listor och ordböcker kan det tyckas vara svårt att få information lagrad i ett PDF-dokument.
Som tur är finns det ett antal bibliotek som gör det enkelt att arbeta med PDF-filer och extrahera data som lagras i PDF-filer. För att lära dig mer om dessa olika bibliotek, låt oss titta på hur du kan extrahera texter, länkar och bilder från PDF-filer. För att följa med, ladda ner följande PDF-fil och spara den i samma katalog som din Python-programfil.
För att extrahera text från PDF-filer med Python kommer vi att använda PyPDF2 bibliotek. PyPDF2 är ett gratis Python-bibliotek med öppen källkod som kan användas för att slå samman, beskära och omvandla sidorna i PDF-filer. Det kan lägga till anpassade data, visningsalternativ och lösenord till PDF-filer. Viktigt är dock att PyPDF2 kan hämta text från PDF-filer.
För att använda PyPDF2 för att extrahera text från PDF-filer, installera den med pip, som är ett paketinstallationsprogram för Python. pip låter dig installera olika Python-paket på din maskin:
1. Kontrollera om du redan har pip installerat genom att köra:
pip --version
Om du inte får tillbaka ett versionsnummer betyder det att pip inte är installerat.
2. För att installera pip, klicka på få pip för att ladda ner installationsskriptet.
Länken öppnar en sida med skriptet för att installera pip enligt nedan:
Högerklicka på sidan och klicka på Spara som för att spara filen. Som standard är namnet på filen get-pip.py
Öppna terminalen och navigera till katalogen med filen get-pip.py du just laddade ner och kör sedan kommandot:
sudo python3 get-pip.py
Detta bör installera pip som visas nedan:
3. Kontrollera att pip har installerats korrekt genom att köra:
pip --version
Om det lyckas bör du få ett versionsnummer:
Med pip installerat kan vi nu börja arbeta med PyPDF2.
1. Installera PyPDF2 genom att utföra följande kommando i terminalen:
pip install PyPDF2
2. Skapa en Python-fil och importera PdfReader från PyPDF2 med följande rad:
from PyPDF2 import PdfReader
PyPDF2-biblioteket tillhandahåller en mängd olika klasser för att arbeta med PDF-filer. En sådan klass är PdfReader, som bland annat kan användas för att öppna PDF-filer, läsa innehållet och extrahera text från PDF-filer.
3. För att börja arbeta med en PDF-fil måste du först öppna filen. För att göra detta, skapa en instans av PdfReader-klassen och skicka in PDF-filen du vill arbeta med:
reader = PdfReader('games.pdf')
Raden ovan instansierar PdfReader och förbereder den för att komma åt innehållet i PDF-filen du anger. Förekomsten lagras i en variabel som kallas reader, som kommer att behöva komma åt en mängd olika metoder och egenskaper som är tillgängliga i klassen PdfReader.
4. För att se om allt fungerar som det ska, skriv ut antalet sidor i PDF:en som du skickade in med följande kod:
print(len(reader.pages))
Produktion:
5
5. Eftersom vår PDF-fil har 5 sidor kan vi komma åt varje sida som är tillgänglig i PDF:en. Räkningen börjar dock från 0, precis som Pythons indexeringskonvention. Därför kommer den första sidan i pdf-filen att vara sidnummer 0. För att hämta första sidan i PDF-filen, lägg till följande rad i din kod:
page1 = reader.pages[0]
Raden ovan hämtar den första sidan i PDF-filen och lagrar den i en variabel med namnet page1.
6. För att extrahera texten på första sidan i PDF-filen, lägg till följande rad:
textPage1 = page1.extract_text()
Detta extraherar texten på första sidan i PDF:en och lagrar innehållet i en variabel som heter textPage1. Du har alltså tillgång till texten på PDF-filens första sida genom variabeln textPage1.
7. För att bekräfta att texten extraherades framgångsrikt kan du skriva ut innehållet i variabeln textPage1. Hela vår kod, som även skriver ut texten på första sidan i PDF-filen, visas nedan:
# 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)
Produktion:
För att extrahera länkar från PDF-filer går vi till PyMuPDF som är ett Python-bibliotek för att extrahera, analysera, konvertera och manipulera data som lagras i dokument som PDF-filer. För att använda PyMuPDF bör du ha Python 3.8 eller senare. För att starta:
1. Installera PyMuPDF genom att köra följande rad i terminalen:
pip install PyMuPDF
2. Importera PyMuPDF till din Python-fil med följande uttalande:
import fitz
3. För att komma åt PDF-filen du vill extrahera länkar från måste du först öppna den. För att öppna den, skriv in följande rad:
doc = fitz.open("games.pdf")
4. När du har öppnat PDF-filen, skriv ut antalet sidor i PDF-filen på följande rad:
print(doc.page_count)
Produktion:
5
4. För att extrahera länkar från en sida i PDF-filen måste vi ladda sidan vi vill extrahera länkar från. För att ladda en sida, skriv in följande rad, där du anger sidnumret du vill ladda in i en funktion som heter load_page()
page = doc.load_page(0)
För att extrahera länkar från första sidan skickar vi in 0(noll). Räkningen av sidor börjar från noll precis som i datastrukturer som arrayer och ordböcker.
5. Extrahera länkarna från sidan med följande rad:
links = page.get_links()
Alla länkar på sidan du angav, i vårt fall sida 1, kommer att extraheras och lagras i variabeln som kallas länkar
6. För att se innehållet i länkvariabeln, skriv ut den så här:
print(links)
Produktion:
Lägg märke till att variabellänkarna innehåller en lista över ordböcker med nyckel-värdepar från den utskrivna utskriften. Varje länk på sidan representeras av en ordbok, med den faktiska länken lagrad under nyckeln ”uri”
7. För att få länkarna från listan över objekt lagrade under variabelnamnlänkarna, iterera genom listan med en for in-sats och skriv ut de specifika länkarna som lagras under nyckel-uri. Hela koden som gör detta visas nedan:
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"])
Produktion:
5 https://www.statista.com/statistics/1292243/software-developers-average-age-when-first-coding/ https://sparkian.com/ https://www.codemonkey.com/
8. För att göra vår kod mer återanvändbar kan vi omfaktorisera den genom att definiera en funktion för att extrahera alla länkar i en PDF och en funktion för att skriva ut alla länkar som finns i en PDF. På så sätt kan du anropa funktionerna med vilken PDF som helst och du får tillbaka alla länkar i PDF:en. Koden som gör detta visas nedan:
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)
Produktion:
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
Från koden ovan tar funktionen extract_link() emot en PDF-fil, itererar genom alla sidor i PDF:en, extraherar alla länkar och returnerar dem. Resultatet av denna funktion lagras i en variabel som heter all_links
Funktionen print_all_links() tar in resultatet av extract_link(), itererar genom listan och skriver ut alla faktiska länkar som finns i PDF-filen som du skickade till funktionen extract_link().
För att extrahera bilder från en PDF kommer vi fortfarande att använda PyMuPDF. Så här extraherar du bilder från en PDF-fil:
1. Importera PyMuPDF, io och PIL. Python Imaging Library (PIL) tillhandahåller verktyg som gör det enkelt att skapa och spara bilder, bland andra funktioner. io tillhandahåller klasser för enkel och effektiv hantering av binär data.
import fitz from io import BytesIO from PIL import Image
2. Öppna PDF-filen som du vill extrahera bilder från:
doc = fitz.open("games.pdf")
3. Ladda sidan du vill extrahera bilder från:
page = doc.load_page(0)
4. PyMuPdf identifierar bilder på en PDF-fil med hjälp av ett korsreferensnummer (xref), som vanligtvis är ett heltal. Varje bild på en PDF-fil har en unik xref. För att extrahera en bild från en PDF måste vi därför först få xref-numret som identifierar den. För att få xref-numret för bilderna på en sida använder vi funktionen get_images() så här:
image_xref = page.get_images() print(image_xref)
Produktion:
[(7, 0, 699, 407, 8, 'DeviceRGB', '', 'X7', 'FlateDecode')]
get_images() returnerar en lista med tupler med information om bilden. Eftersom vi bara har en bild på första sidan så finns det bara en tuppel. Det första elementet i tuppeln representerar xref för bilden på sidan. Därför är xref för bilden på första sidan 7.
5. För att extrahera xref-värdet för bilden från listan över tuplar använder vi koden nedan:
# get xref value of the image xref_value = image_xref[0][0] print(xref_value)
Produktion:
[(7, 0, 699, 407, 8, 'DeviceRGB', '', 'X7', 'FlateDecode')] 7
6. Eftersom du nu har xref som identifierar en bild på PDF:en, kan du extrahera bilden med hjälp av funktionen extract_image() så här:
img_dictionary = doc.extract_image(xref_value)
Denna funktion returnerar dock inte den faktiska bilden. Istället returnerar den en ordbok som innehåller bildens binära bilddata och metadata om bilden, bland annat.
7. Från ordlistan som returneras av funktionen extract_image() kontrollerar du filtillägget för den extraherade bilden. Filtillägget lagras under nyckeln ”ext”:
# get file extenstion img_extension = img_dictionary["ext"] print(img_extension)
Produktion:
png
8. Extrahera bildbinärfilerna från ordboken lagrad i img_dictionary. Bildbinärerna lagras under nyckeln ”bild”
# get the actual image binary data img_binary = img_dictionary["image"]
9. Skapa ett BytesIO-objekt och initiera det med de binära bilddata som representerar bilden. Detta skapar ett filliknande objekt som kan bearbetas av Python-bibliotek som PIL så att du kan spara bilden.
# create a BytesIO object to work with the image bytes image_io = BytesIO(img_binary)
10. Öppna och analysera bilddata som lagrats i BytesIO-objektet med namnet image_io med hjälp av PIL-biblioteket. Detta är viktigt eftersom det tillåter PIL-biblioteket att bestämma bildformatet för bilden du försöker arbeta med, i det här fallet en PNG. Efter att ha upptäckt bildformatet skapar PIL ett bildobjekt som kan manipuleras med PIL-funktioner och metoder, såsom save()-metoden, för att spara bilden till lokal lagring.
# open the image using Pillow image = Image.open(image_io)
11. Ange sökvägen där du vill spara bilden.
output_path = "image_1.png"
Eftersom sökvägen ovan endast innehåller namnet på filen med dess tillägg, kommer den extraherade bilden att sparas i samma katalog som Python-filen som innehåller detta program. Bilden kommer att sparas som image_1.png. PNG-tillägget är viktigt för att det ska matcha bildens ursprungliga tillägg.
12. Spara bilden och stäng ByteIO-objektet.
# save the image image.save(output_path) # Close the BytesIO object image_io.close()
Hela koden för att extrahera en bild från en PDF-fil visas nedan:
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()
Kör koden och gå till mappen som innehåller din Python-fil; du bör se den extraherade bilden med namnet image_1.png, som visas nedan:
Slutsats
För att få mer övning med att extrahera länkar, bilder och texter från PDF-filer, försök att omfaktorisera koden i exemplen för att göra dem mer återanvändbara, som visas i länkexemplet. På så sätt behöver du bara skicka in en PDF-fil, och ditt Python-program extraherar alla länkar, bilder eller text i hela PDF-filen. Glad kodning!
Du kan också utforska några bästa PDF-API:er för alla affärsbehov.