← Back to list

Convert Scanned PDFs to Searchable PDFs Using Python: Full Guide

Scanned PDFs are essentially images wrapped in a PDF container. That means you can view them — but you can’t search, copy, or extract text…

Alexander Stock in Python in Plain English · 2026-04-22 02:19 · 0 claps · 3.7 min read
#python #scanned-pdf #searchable-pdf #convert
Open on Medium ↗
Wiki topics: ☁️ · DevOps & Cloud

Convert Scanned PDFs to Searchable PDFs Using Python: Full Guide

Scanned PDFs are essentially images wrapped in a PDF container. That means you can view them — but you can’t search, copy, or extract text. If you’ve ever tried to copy content from a scanned invoice or document and failed, you’ve hit this exact limitation.

The solution? OCR (Optical Character Recognition).

In this guide, you’ll learn how to convert scanned PDFs into fully searchable PDFs using Python. We’ll walk through setup, dependencies, language configuration, and a clean, production-ready code example.

🔍 What You’ll Need

To perform OCR on PDFs in Python, we’ll rely on two key components:

1. ocrmypdf (Python Library)

A powerful wrapper that combines OCR and PDF processing into a single command.

2. Tesseract OCR Engine

The underlying OCR engine used by ocrmypdf.

⚙️ Installation

Step 1: Install ocrmypdf

pip install ocrmypdf

Step 2: Install Tesseract OCR

Windows

Download and install from the official Tesseract repository.

👉 During installation, pay close attention to these options:

  • Additional language data (download)
  • Additional script data (download)

If you don’t check these, only the English language module will be installed by default.

This is one of the most common pitfalls — users later try to run OCR in Chinese or Japanese and get errors because the language data simply isn’t there.

macOS (Homebrew)

brew install tesseract

Linux (Ubuntu/Debian)

sudo apt install tesseract-ocr

📁 Configuring Tessdata (Important)

Tesseract needs to know where its language data files (.traineddata) are located.

On Windows, you typically need to set the environment variable manually:

os.environ["TESSDATA_PREFIX"] = r"C:\Program Files\Tesseract-OCR\tessdata"

If this path is incorrect or missing, OCR will fail with language-related errors.

🌍 Supported Languages & Enum Design

To make language selection safer and more developer-friendly, the code uses an Enum:

class OcrLanguage(Enum):
    """Supported OCR languages using ISO 639-2 codes."""
    ENGLISH = "eng"
    SIMPLIFIED_CHINESE = "chi_sim"
    TRADITIONAL_CHINESE = "chi_tra"
    CHINESE_ENGLISH = "chi_sim+eng"
    JAPANESE = "jpn"
    KOREAN = "kor"

Why use an Enum?

  • ❌ Avoid typos like "engg" or "chn"
  • ✅ Autocomplete support in IDEs
  • ✅ Cleaner, self-documenting code

➕ How to Add More Languages

You can easily extend the OcrLanguage enum.

Step 1: Install the language data

Make sure the corresponding .traineddata file exists in your tessdata folder.

Examples:

  • fra.traineddata → French
  • deu.traineddata → German
  • spa.traineddata → Spanish

Step 2: Extend the Enum

class OcrLanguage(Enum):
    ENGLISH = "eng"
    FRENCH = "fra"
    GERMAN = "deu"
    SPANISH = "spa"

Step 3: Use it

language=OcrLanguage.FRENCH

🧠 Multi-Language OCR

You can combine multiple languages:

CHINESE_ENGLISH = "chi_sim+eng"

This is especially useful for:

  • Bilingual documents
  • Mixed-language invoices
  • Academic papers

🚀 Full Code Example

Here’s a complete working script:

import ocrmypdf
from enum import Enum
import os

# ==============================================
# Set Tesseract data directory (Windows only)
# ==============================================
os.environ["TESSDATA_PREFIX"] = r"C:\Program Files\Tesseract-OCR\tessdata"

# ==============================================
# OCR Language Enum (No typos, easy to select)
# ==============================================
class OcrLanguage(Enum):
    """Supported OCR languages using ISO 639-2 codes."""
    ENGLISH = "eng"
    SIMPLIFIED_CHINESE = "chi_sim"
    TRADITIONAL_CHINESE = "chi_tra"
    CHINESE_ENGLISH = "chi_sim+eng"
    JAPANESE = "jpn"
    KOREAN = "kor"

# ==============================================
# Core conversion function
# ==============================================
def convert_scanned_pdf_to_searchable(
    input_pdf_path: str,
    output_pdf_path: str,
    language: OcrLanguage
):
    """
    Convert image-based (scanned) PDF to a searchable PDF using OCR.

    Args:
        input_pdf_path: Path to your scanned input PDF
        output_pdf_path: Path to save the new searchable PDF
        language: OCR language selected from the OcrLanguage enum
    """
    try:
        # Run OCR and generate optimized searchable PDF
        ocrmypdf.ocr(
            input_file=input_pdf_path,
            output_file=output_pdf_path,
            language=language.value,
            optimize=1,
            force_ocr=True
        )
        print(f"✅ Success! Searchable PDF saved to: {output_pdf_path}")

    except Exception as error:
        print(f"❌ Error during conversion: {str(error)}")

# ==============================================
# Run the converter
# ==============================================
if __name__ == "__main__":
    # Configure your file paths here
    INPUT_FILE = "ScannedPDF.pdf"
    OUTPUT_FILE = "searchable.pdf"

    # Select language from the Enum (safe and easy)
    convert_scanned_pdf_to_searchable(
        input_pdf_path=INPUT_FILE,
        output_pdf_path=OUTPUT_FILE,
        language=OcrLanguage.ENGLISH 
    )

Output:

Sacnned PDF becomes selectable

Sacnned PDF becomes selectable

⚡ Key Parameters Explained

  • language → Controls OCR language(s)
  • optimize=1 → Reduces file size while keeping quality
  • force_ocr=True → Forces OCR even if text is already detected

⚠️ Common Pitfalls

1. Missing Language Data

If you see errors like:

Error opening data file...

→ You likely didn’t install the language pack.

2. Wrong Tessdata Path

Double-check:

TESSDATA_PREFIX

3. Low OCR Accuracy

OCR quality depends heavily on:

  • Image resolution (300 DPI recommended)
  • Noise / blur
  • Font clarity

💡 Pro Tips

Improve OCR Accuracy

  • Preprocess PDFs (deskew, denoise)
  • Convert to grayscale before OCR
  • Ensure proper DPI

Batch Processing

Wrap the function in a loop:

for file in os.listdir("input_folder"):
    if file.endswith(".pdf"):
        convert_scanned_pdf_to_searchable(...)

Preserve Original File

ocrmypdf adds a hidden text layer without altering the visual layout—so your original PDF appearance stays intact.

🧾 Final Thoughts

With just a few lines of Python, you can turn unusable scanned PDFs into fully searchable, copyable, and indexable documents.

The combination of:

  • ocrmypdf
  • Tesseract
  • Structured language handling via Enum

…gives you a robust, scalable OCR pipeline suitable for everything from personal use to enterprise workflows.

If you’re dealing with large volumes of scanned files, this approach can save hours of manual work — and unlock your data instantly.


메타데이터
post_id
7742c633ecf5
slug
convert-scanned-pdfs-to-searchable-using-python-full-guide-7742c633ecf5
url
https://medium.com/@alexaae9/convert-scanned-pdfs-to-searchable-using-python-full-guide-7742c633ecf5
canonical_url
https://medium.com/@alexaae9/convert-scanned-pdfs-to-searchable-using-python-full-guide-7742c633ecf5
author_url
https://medium.com/@alexaae9
status
ok
fetched_at
2026-06-17 19:05:49