Skip to content

How to Search for a String in a PDF File in Python

Learn to search PDF text efficiently in Python using PyPDF2 for basic needs or PyMuPDF for advanced features like location tracking and regex pattern matching.

Searching for specific text within PDF documents is essential for automating document analysis, compliance auditing, legal discovery, and research workflows. Unlike plain text files, PDFs are binary formats with compressed data streams and complex layout structures that standard file reading methods cannot process. This guide demonstrates how to effectively search PDF content using Python libraries designed for PDF parsing.

Quick Solution with PyPDF2

PyPDF2 is a popular, lightweight library suitable for basic text extraction and searching:

import PyPDF2

def search_pdf(file_path, search_term):
    """
    Search for a term in a PDF file.
    
    Returns list of page numbers where the term appears.
    """
    matches = []
    
    with open(file_path, 'rb') as file:
        reader = PyPDF2.PdfReader(file)
        
        for page_num, page in enumerate(reader.pages, start=1):
            text = page.extract_text()
            
            if text and search_term.lower() in text.lower():
                matches.append(page_num)
    
    return matches

High-Performance Search with PyMuPDF

For production applications, PyMuPDF (imported as fitz) offers superior speed, accuracy, and additional features like coordinate detection:

import fitz  # pip install pymupdf

def search_pdf_advanced(file_path, search_term):
    """
    Search PDF with location information for each match.
    
    Returns dict with page numbers and match coordinates.
    """
    results = {}
    
    doc = fitz.open(file_path)
    
    for page in doc:
        matches = page.search_for(search_term)
        
        if matches:
            results[page.number + 1] = {
                "count": len(matches),
                "locations": [(rect.x0, rect.y0) for rect in matches]
            }
    
    doc.close()
    return results

Searching Multiple PDFs

Process entire directories of PDF files efficiently:

import fitz
from pathlib import Path

def search_multiple_pdfs(directory, search_term, extension="*.pdf"):
    """Search for a term across all PDFs in a directory."""
    results = {}
    
    pdf_files = Path(directory).glob(extension)
    
    for pdf_path in pdf_files:
        try:
            doc = fitz.open(pdf_path)
            file_matches = []
            
            for page in doc:
                if page.search_for(search_term):
                    file_matches.append(page.number + 1)
            
            if file_matches:
                results[pdf_path.name] = file_matches
            
            doc.close()
            
        except Exception as e:
            print(f"Error processing {pdf_path.name}: {e}")
    
    return results

Case-Sensitive and Pattern Matching

For more sophisticated searches, combine PDF extraction with regular expressions:

import fitz
import re

def regex_search_pdf(file_path, pattern):
    """
    Search PDF using regular expression patterns.
    
    Useful for finding emails, phone numbers, dates, etc.
    """
    results = {}
    compiled_pattern = re.compile(pattern, re.IGNORECASE)
    
    doc = fitz.open(file_path)
    
    for page in doc:
        text = page.get_text()
        matches = compiled_pattern.findall(text)
        
        if matches:
            results[page.number + 1] = matches
    
    doc.close()
    return results

Library Comparison

Library Speed Accuracy Best For
PyPDF2 Moderate Basic Simple scripts, small files
PyMuPDF Excellent Excellent Production tools, large files
pdfminer.six Slower Excellent Complex layout analysis

Handling Scanned PDFs

Scanned documents contain images rather than extractable text. These require OCR (Optical Character Recognition):

import fitz
import pytesseract
from PIL import Image
import io

def search_scanned_pdf(file_path, search_term):
    """Search scanned PDF using OCR."""
    results = []
    
    doc = fitz.open(file_path)
    
    for page_num, page in enumerate(doc, start=1):
        pix = page.get_pixmap(matrix=fitz.Matrix(2, 2))
        img = Image.open(io.BytesIO(pix.tobytes()))
        
        text = pytesseract.image_to_string(img)
        
        if search_term.lower() in text.lower():
            results.append(page_num)
    
    doc.close()
    return results

Memory Management

When processing many PDFs, proper resource cleanup prevents memory issues:

import fitz

def search_large_batch(file_paths, search_term):
    """Memory-efficient batch processing."""
    for path in file_paths:
        doc = None
        try:
            doc = fitz.open(path)
            for page in doc:
                if page.search_for(search_term):
                    yield path, page.number + 1
        finally:
            if doc:
                doc.close()  # Always close to free memory

By leveraging these PDF parsing libraries, you can automate text searches across thousands of documents for compliance checking, content auditing, and information extraction workflows.

Navigation