Prerequisites and System Dependencies
Processing image-based PDF documents requires a specific stack. The workflow relies on pdf2image for rasterizing document pages, pytesseract as the Python binding for Tesseract OCR, and native system utilities for PDF parsing and character recognition.
Install the core Python packages:
pip install pdf2image pytesseract
Ensure the host operating system has poppler-utils (for PDF rendering) and the standalone Tesseract OCR engine installed. Both must be reachable via the system PATH environment varible.
Converting PDF Pages to Images
Scanned files contain bitmap data rather than selectable text layers. The first step is converting each page into a high-resolution PNG or JPEG. The convert_from_path method handles this transformation while allowing memory optimization through explicit page range targeting.
Optical Character Recognition Pipeline
Once rendered, each page image is processed by the OCR engine. Tesseract performs layout analysis and returns raw string output. Scanned tables often produce fragmented tokens, requiring post-processing to reconstruct columnar relationships accurately.
Data Normalization and CSV Export
Raw OCR results typically contain newline artifacts, bounding box brackets, and trailing whitespace. A dedicated normalization routine filters empty entries, strips formatting noise, and splits rows by whitespace. The structured records are then flushed to a CSV file using Python's standard library, guaranteeing proper delimiter handling and encoding consistency.
Complete Implementation
The following script consolidates conversion, recognition, cleaning, and export into a single executable module with type hints and error handling.
import os
import csv
import logging
from pathlib import Path
from pdf2image import convert_from_path
import pytesseract
logging.basicConfig(level=logging.INFO, format='%(levelname)s: %(message)s')
def configure_tesseract(binary_path: str = None):
"""Override Tesseract binary location when not configured in system PATH."""
if binary_path:
pytesseract.pytesseract.tesseract_cmd = binary_path
def process_scanned_pdf(
source_document: str,
target_csv: str,
language: str = "eng",
page_bounds: tuple = None
) -> None:
if not os.path.isfile(source_document):
raise FileNotFoundError(f"Target file not located: {source_document}")
configure_tesseract()
cache_dir = Path(os.path.dirname(os.path.abspath(source_document))) / "render_cache"
cache_dir.mkdir(exist_ok=True)
logging.info("Rasterizing document pages...")
render_args = {
'dpi': 300,
'fmt': 'png',
'output_folder': str(cache_dir),
'first_page': page_bounds[0] if page_bounds else None,
'last_page': page_bounds[1] if page_bounds else None
}
try:
page_renderings = convert_from_path(source_document, **render_args)
except Exception as e:
raise RuntimeError("PDF rendering failed. Verify poppler-utils installation.") from e
logging.info(f"Running OCR on {len(page_renderings)} pages...")
raw_segments = []
for img in page_renderings:
segment_text = pytesseract.image_to_string(img, lang=language)
raw_segments.append(segment_text)
logging.info("Cleaning tokens and structuring data...")
formatted_records = []
for block in raw_segments:
# Split by whitespace to isolate columns
tokens = block.split()
# Remove empty strings and strip bracket artifacts common in OCR output
cleaned_tokens = [
token.strip().strip('[]')
for token in tokens
if token.strip()
]
# Adjust length condition based on expected table structure
if len(cleaned_tokens) == 3:
formatted_records.append(cleaned_tokens)
logging.info(f"Saving {len(formatted_records)} records to {target_csv}...")
with open(target_csv, mode='w', encoding='utf-8', newline='') as sheet:
writer = csv.writer(sheet)
writer.writerow(['Column_A', 'Column_B', 'Column_C'])
writer.writerows(formatted_records)
# Purge temporary cache
for file in cache_dir.iterdir():
file.unlink()
cache_dir.rmdir()
if __name__ == "__main__":
pdf_file = "scanned_report.pdf"
csv_output = "extracted_data.csv"
process_scanned_pdf(pdf_file, csv_output, language="chi_sim+eng", page_bounds=(1, 5))
Troubleshooting Environment Configuration
Two dependency errors commonly interrupt execution:
-
PDFInfoNotInstalledError: Occurs whenpopplerbinaries are missing. Install via your package manager (apt install poppler-utilson Debian/Ubuntu,brew install poppleron macOS) and verify the/bindirectory is included inPATH. Alternatively, pass the absolute path directly toconvert_from_pathusing thepoppler_pathargument. -
TesseractNotFoundError: Indicates the OCR engine is absent or unregistered. Download the official installer, complete setup, and add the installationbinfolder to system environment variibles. For immediate script-level overrides without modifying OS settings, assign the executable path explicitly:pytesseract.pytesseract.tesseract_cmd = r'absolute\path\to\tesseract.exe'before invoking any OCR functions.