Už se mi stalo, že jsem potřeboval extrahovat text nebo tabulky z PDF, ale pokaždé jsem si musel znovu zjišťovat, jak na to. Proto si to sem ukládám jako „rabbit hole“ poznámky pro příště. Jestli jsi tady poprvé, tak vítej v dírě 🐇🌍.
Co tenhle skript umí?
- Extrahuje text z PDF pomocí OCR (Tesseract).
- Uloží OCR výsledky do JSON a Excelu.
- Extrahuje tabulky z PDF pomocí
pdfplumber
. - Zachová strukturu tabulek a exportuje je do JSON a Excelu.
- Loguje průběh, aby šlo snadno zjistit, kde se co pokazilo.
1. OCR – Extrakce textu z PDF
Tento kód převede PDF na obrázky, spustí OCR (Tesseract) a uloží výsledky.
import json
import pymupdf # PyMuPDF
from pdf2image import convert_from_path
import pytesseract
from PIL import Image
import pandas as pd
import os
PDF_FILE = "test_1.pdf"
OUTPUT_JSON = "output.json"
OUTPUT_EXCEL = "output.xlsx"
def log(message):
print(f"[INFO] {message}")
def extract_text_ocr(pdf_path):
log(f"Načítám PDF: {pdf_path}")
images = convert_from_path(pdf_path, dpi=300)
log(f"PDF převedeno na {len(images)} obrázků.")
ocr_text = []
for i, img in enumerate(images):
log(f"Spouštím OCR na stránce {i+1}...")
text = pytesseract.image_to_string(img, lang="ces")
ocr_text.append({"page": i + 1, "text": text.strip()})
log("OCR dokončeno.")
return ocr_text
def parse_data(ocr_results):
log("Parsování dat - zatím neimplementováno.")
return {}
def save_to_json(data, filename):
with open(filename, "w", encoding="utf-8") as f:
json.dump(data, f, ensure_ascii=False, indent=4)
log(f"Výstup uložen do: {filename}")
def save_to_excel(ocr_results, filename):
log("Ukládám výstup do Excelu...")
df = pd.DataFrame(ocr_results)
df.to_excel(filename, index=False, engine="openpyxl")
log(f"Excel uložen jako: {filename}")
def main():
if not os.path.exists(PDF_FILE):
log(f"Chyba: Soubor {PDF_FILE} neexistuje!")
return
ocr_results = extract_text_ocr(PDF_FILE)
parsed_data = parse_data(ocr_results)
output_data = {
"ocr_results": ocr_results,
"parsed_data": parsed_data
}
save_to_json(output_data, OUTPUT_JSON)
save_to_excel(ocr_results, OUTPUT_EXCEL)
if __name__ == "__main__":
main()
Vylepšení do budoucna:
- Čistější správa dočasných souborů.
- Automatická detekce tabulek pro lepší strukturovaný výsledek.
2. Extrakce tabulek z PDF
Pokud PDF obsahuje tabulky, je lepší použít pdfplumber
, který je umí přímo identifikovat.
import os
import json
import pandas as pd
import pdfplumber
def log(message):
print(f"[INFO] {message}")
def extract_tables_from_pdf(pdf_path):
tables_data = []
with pdfplumber.open(pdf_path) as pdf:
for page_num, page in enumerate(pdf.pages):
tables = page.extract_tables()
for table in tables:
tables_data.append({
"page": page_num + 1,
"data": [row for row in table if any(row)] # Odstraníme prázdné řádky
})
return tables_data
def save_json(data, filename):
with open(filename, "w", encoding="utf-8") as f:
json.dump(data, f, ensure_ascii=False, indent=4)
log(f"Výstup uložen do: {filename}")
def save_excel(data, filename):
log("Ukládám výstup do Excelu...")
df_data = []
for entry in data:
for row in entry["data"]:
df_data.append([entry["page"]] + row)
df = pd.DataFrame(df_data)
df.to_excel(filename, index=False, header=False, engine="openpyxl")
log(f"Excel uložen jako: {filename}")
def process_pdf(pdf_path, output_dir):
log(f"Zpracovávám: {pdf_path}")
tables = extract_tables_from_pdf(pdf_path)
base_name = os.path.splitext(os.path.basename(pdf_path))[0]
json_path = os.path.join(output_dir, f"{base_name}.json")
excel_path = os.path.join(output_dir, f"{base_name}.xlsx")
save_json(tables, json_path)
save_excel(tables, excel_path)
log(f"Dokončeno: {pdf_path}")
def main():
input_pdf = "rocenka_23.pdf"
output_dir = "output23"
os.makedirs(output_dir, exist_ok=True)
process_pdf(input_pdf, output_dir)
if __name__ == "__main__":
main()
Vylepšení do budoucna:
- Lepší detekce tabulek, pokud jsou nesouvislé.
- Uložení dat i s hlavičkami, pokud jsou detekovatelé.
Napsat komentář