Jak extrahovat text, odkazy a obrázky ze souborů PDF pomocí Pythonu

Python je velmi všestranný jazyk a vývojáři Pythonu musí často pracovat s různými soubory a získávat informace v nich uložené ke zpracování. Jedním z oblíbených formátů souborů, se kterými se jako vývojáři Pythonu musíte setkat, je formát Portable Document Format, známý jako PDF.

Soubory PDF mohou obsahovat text, obrázky a odkazy. Při zpracovávání dat v programu Python můžete zjistit, že potřebujete extrahovat data uložená v dokumentu PDF. Na rozdíl od datových struktur, jako jsou n-tice, seznamy a slovníky, se získání informací uložených v dokumentu PDF může zdát jako obtížná věc.

Naštěstí existuje řada knihoven, které usnadňují práci s PDF a extrahují data uložená v souborech PDF. Chcete-li se dozvědět o těchto různých knihovnách, podívejme se, jak můžete extrahovat texty, odkazy a obrázky ze souborů PDF. Chcete-li pokračovat, stáhněte si následující soubor PDF a uložte jej do stejného adresáře jako soubor programu Python.

Chcete-li extrahovat text ze souborů PDF pomocí Pythonu, použijeme PyPDF2 knihovna. PyPDF2 je bezplatná a open source knihovna Pythonu, kterou lze použít ke sloučení, oříznutí a transformaci stránek souborů PDF. Do souborů PDF může přidávat vlastní data, možnosti zobrazení a hesla. Důležité však je, že PyPDF2 dokáže načíst text ze souborů PDF.

Chcete-li použít PyPDF2 k extrahování textu ze souborů PDF, nainstalujte jej pomocí pip, což je instalátor balíčků pro Python. pip vám umožňuje nainstalovat různé balíčky Pythonu na váš počítač:

1. Zkontrolujte, zda již máte nainstalovaný pip spuštěním:

pip --version

Pokud nedostanete zpět číslo verze, znamená to, že pip není nainstalován.

2. Chcete-li nainstalovat pip, klikněte na dostat pip stáhnout jeho instalační skript.

Odkaz otevře stránku se skriptem pro instalaci pip, jak je znázorněno níže:

Klikněte pravým tlačítkem na stránku a kliknutím na Uložit jako soubor uložte. Ve výchozím nastavení je název souboru get-pip.py

Otevřete terminál a přejděte do adresáře se souborem get-pip.py, který jste právě stáhli, a poté spusťte příkaz:

sudo python3 get-pip.py

To by mělo nainstalovat pip, jak je znázorněno níže:

3. Zkontrolujte, zda byl pip úspěšně nainstalován spuštěním:

pip --version

V případě úspěchu byste měli získat číslo verze:

S nainstalovaným pipem můžeme nyní začít pracovat s PyPDF2.

1. Nainstalujte PyPDF2 provedením následujícího příkazu v terminálu:

pip install PyPDF2

2. Vytvořte soubor Python a importujte PdfReader z PyPDF2 pomocí následujícího řádku:

from PyPDF2 import PdfReader

Knihovna PyPDF2 poskytuje různé třídy pro práci se soubory PDF. Jednou z takových tříd je PdfReader, kterou lze mimo jiné použít k otevírání souborů PDF, čtení obsahu a extrahování textu ze souborů PDF.

3. Chcete-li začít pracovat se souborem PDF, musíte soubor nejprve otevřít. Chcete-li to provést, vytvořte instanci třídy PdfReader a předejte soubor PDF, se kterým chcete pracovat:

reader = PdfReader('games.pdf')

Řádek výše vytvoří instanci PdfReader a připraví jej pro přístup k obsahu souboru PDF, který určíte. Instance je uložena v proměnné nazvané reader, která bude mít přístup k řadě metod a vlastností dostupných ve třídě PdfReader.

  Jak vytvořit kryptopeněženku a převzít kontrolu nad svým digitálním bohatstvím

4. Chcete-li zjistit, zda vše funguje správně, vytiskněte počet stránek v souboru PDF, který jste předali, pomocí následujícího kódu:

print(len(reader.pages))

Výstup:

5

5. Protože náš soubor PDF má 5 stránek, máme přístup ke každé stránce dostupné v PDF. Počítání však začíná od 0, stejně jako indexovací konvence Pythonu. První stránka v souboru PDF bude tedy číslo stránky 0. Chcete-li načíst první stránku PDF, přidejte do kódu následující řádek:

page1 = reader.pages[0]

Řádek výše načte první stránku v souboru PDF a uloží ji do proměnné s názvem page1.

6. Chcete-li extrahovat text na první stránce souboru PDF, přidejte následující řádek:

textPage1 = page1.extract_text()

Tím se extrahuje text na první stránce PDF a obsah se uloží do proměnné s názvem textPage1. Máte tak přístup k textu na první stránce souboru PDF prostřednictvím proměnné textPage1.

7. Chcete-li potvrdit, že byl text extrahován úspěšně, můžete vytisknout obsah proměnné textPage1. Celý náš kód, který také vytiskne text na první stránce souboru PDF, je zobrazen níže:

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

Výstup:

Chcete-li extrahovat odkazy ze souborů PDF, přejdeme do PyMuPDF, což je knihovna Pythonu pro extrahování, analýzu, konverzi a manipulaci s daty uloženými v dokumentech, jako jsou soubory PDF. Chcete-li používat PyMuPDF, měli byste mít Python 3.8 nebo novější. Začít:

1. Nainstalujte PyMuPDF provedením následujícího řádku v terminálu:

pip install PyMuPDF

2. Importujte PyMuPDF do svého souboru Python pomocí následujícího příkazu:

import fitz

3. Chcete-li získat přístup k PDF, ze kterého chcete extrahovat odkazy, musíte jej nejprve otevřít. Chcete-li jej otevřít, zadejte následující řádek:

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

4. Po otevření souboru PDF vytiskněte počet stránek v PDF pomocí následujícího řádku:

print(doc.page_count)

Výstup:

5

4. Chcete-li extrahovat odkazy ze stránky v souboru PDF, musíme načíst stránku, ze které chceme odkazy extrahovat. Chcete-li načíst stránku, zadejte následující řádek, kde předáte číslo stránky, kterou chcete načíst, do funkce nazvané load_page()

page = doc.load_page(0)

Abychom extrahovali odkazy z první stránky, předáme 0 (nula). Počítání stránek začíná od nuly stejně jako v datových strukturách, jako jsou pole a slovníky.

5. Extrahujte odkazy ze stránky pomocí následujícího řádku:

links = page.get_links()

Všechny odkazy na vámi zadané stránce, v našem případě na stránce 1, budou extrahovány a uloženy do proměnné nazvané odkazy

6. Chcete-li zobrazit obsah proměnné odkazů, vytiskněte ji takto:

print(links)

Výstup:

Z tištěného výstupu si všimněte, že odkazy na proměnné obsahují seznam slovníků s páry klíč–hodnota. Každý odkaz na stránce je reprezentován slovníkem, přičemž aktuální odkaz je uložen pod klíčem „uri“

7. Chcete-li získat odkazy ze seznamu objektů uložených pod proměnnými odkazy, iterujte seznam pomocí příkazu for in a vytiskněte konkrétní odkazy uložené pod klíčem uri. Celý kód, který to dělá, je zobrazen níže:

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

Výstup:

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

8. Aby byl náš kód opětovněji použitelný, můžeme jej refaktorovat definováním funkce pro extrahování všech odkazů v PDF a funkce pro tisk všech odkazů nalezených v PDF. Tímto způsobem můžete volat funkce s jakýmkoli PDF a získáte zpět všechny odkazy v PDF. Kód, který to dělá, je zobrazen níže:

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)

Výstup:

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

Z výše uvedeného kódu funkce extract_link() přijme soubor PDF, iteruje všechny stránky v PDF, extrahuje všechny odkazy a vrátí je. Výsledek této funkce je uložen v proměnné s názvem all_links

  Hands On: Jak hrát hry PS4 na iPhonu nebo iPadu

Funkce print_all_links() převezme výsledek extract_link(), iteruje seznam a vytiskne všechny skutečné odkazy nalezené v PDF, které jste předali do funkce extract_link().

K extrahování obrázků z PDF budeme stále používat PyMuPDF. Chcete-li extrahovat obrázky ze souboru PDF:

1. Importujte PyMuPDF, io a PIL. Python Imaging Library (PIL) poskytuje nástroje, které kromě jiných funkcí usnadňují vytváření a ukládání obrázků. io poskytuje třídy pro snadnou a efektivní manipulaci s binárními daty.

import fitz
from io import BytesIO
from PIL import Image

2. Otevřete soubor PDF, ze kterého chcete extrahovat obrázky:

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

3. Načtěte stránku, ze které chcete extrahovat obrázky:

page = doc.load_page(0)

4. PyMuPdf identifikuje obrázky v souboru PDF pomocí křížového referenčního čísla (xref), což je obvykle celé číslo. Každý obrázek v souboru PDF má jedinečnou externí referenci. Proto, abychom extrahovali obrázek z PDF, musíme nejprve získat číslo externí reference, které jej identifikuje. Abychom získali xref číslo obrázků na stránce, použijeme funkci get_images() takto:

image_xref = page.get_images()
print(image_xref)

Výstup:

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

get_images() vrací seznam n-tic s informacemi o obrázku. Vzhledem k tomu, že na první stránce máme pouze jeden obrázek, je zde pouze jedna n-tice. První prvek v n-tice představuje externí referenci obrázku na stránce. Proto je xref obrázku na první stránce 7.

5. K extrahování hodnoty xref pro obrázek ze seznamu n-tic použijeme níže uvedený kód:

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

Výstup:

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

6. Protože nyní máte externí referenci, která identifikuje obrázek v PDF, můžete obrázek extrahovat pomocí funkce extract_image() takto:

img_dictionary = doc.extract_image(xref_value)

Tato funkce však nevrací skutečný obraz. Místo toho vrací slovník obsahující mimo jiné binární obrazová data obrázku a metadata o obrázku.

  Oprava Scripted Diagnostics Nativní hostitel nefunguje

7. Ve slovníku vráceném funkcí extract_image() zkontrolujte příponu souboru extrahovaného obrázku. Přípona souboru je uložena pod klíčem „ext“:

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

Výstup:

png

8. Extrahujte binární soubory obrázků ze slovníku uloženého v img_dictionary. Binární soubory obrázků jsou uloženy pod klíčem „image“

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

9. Vytvořte objekt BytesIO a inicializujte jej s daty binárního obrazu, která představují obraz. Tím se vytvoří objekt podobný souboru, který lze zpracovat knihovnami Pythonu, jako je PIL, abyste mohli uložit obrázek.

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

10. Otevřete a analyzujte data obrázku uložená v objektu BytesIO s názvem image_io pomocí knihovny PIL. To je důležité, protože umožňuje knihovně PIL určit formát obrázku, se kterým se pokoušíte pracovat, v tomto případě PNG. Po zjištění formátu obrázku PIL vytvoří objekt obrázku, se kterým lze manipulovat pomocí funkcí a metod PIL, jako je metoda save() a uložit obrázek do místního úložiště.

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

11. Zadejte cestu, kam chcete obrázek uložit.

output_path = "image_1.png"

Protože výše uvedená cesta obsahuje pouze název souboru s jeho příponou, bude extrahovaný obrázek uložen ve stejném adresáři jako soubor Python obsahující tento program. Obrázek bude uložen jako image_1.png. Přípona PNG je důležitá, aby odpovídala původní příponě obrázku.

12. Uložte obraz a zavřete objekt ByteIO.

# save the image
image.save(output_path)

# Close the BytesIO object 
image_io.close()

Celý kód pro extrahování obrázku ze souboru PDF je zobrazen níže:

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

Spusťte kód a přejděte do složky obsahující váš soubor Python; měli byste vidět extrahovaný obrázek s názvem image_1.png, jak je ukázáno níže:

Závěr

Chcete-li si více procvičit extrahování odkazů, obrázků a textů z PDF, zkuste kód v příkladech přefaktorovat, aby byly znovu použitelné, jak ukazuje příklad odkazů. Tímto způsobem budete muset předat pouze soubor PDF a váš program Python extrahuje všechny odkazy, obrázky nebo text v celém PDF. Šťastné kódování!

Můžete také prozkoumat některá nejlepší PDF API pro každou obchodní potřebu.