如何使用 Python 從 PDF 提取文字 (3 個函式庫比較)

Janet L. HarrisJanet L. Harris·更新於: 2026年10月30日·閱讀約 6 分鐘

從 PDF 提取文字看似簡單,但任何嘗試過的開發人員都知道,這是一個充滿例外、版面混亂和頑固的圖像式文件的領域。本指南將為您釐清這些困擾。我們將從直接比較最適合此任務的 Python 函式庫開始,讓您能立即為您的專案選擇正確的工具。

extract-text-from-pdf-python.jpg

接著,我們將逐步介紹三個最有效的函式庫—PyPDF2、pdfplumber 和 PyMuPDF (Fitz)—的程式碼範例,涵蓋從基本文字抓取到處理複雜表格的所有內容。我們還將解決最艱鉅的挑戰:需要光學字元辨識 (OCR) 的掃描 PDF,並向您展示一種實用的方法來處理它們,而無需複雜的本地設定。最後,您將掌握程式碼和策略,可靠地自動化您的 PDF 處理工作流程。

快速評斷:最佳 PDF 文字提取 Python 函式庫

在我們深入程式碼之前,這裡是對主要競爭者的高層次概述。您的選擇將完全取決於您需要速度、簡潔性還是精確的版面分析。

函式庫最適合版面/表格處理效能易用性 (1-5)
PyPDF2簡單、純文字文件;基本 PDF 操作(合併/分割)差(提取文字流,無位置資料)中等5
pdfplumber從表格提取資料;具有結構化版面的文件極佳(提供文字、線條和矩形的座標)較慢4
PyMuPDF (Fitz)高速批次處理;處理圖像和註釋良好(可提取帶有基本位置資訊的文字)極佳(最快)4

總結: 對於最簡單的情況,請從 PyPDF2 開始。一旦遇到表格,請轉向 pdfplumber。當效能是您的主要考量時,請選擇 PyMuPDF。

開始之前:設定您的 Python 環境

為了保持專案依賴項的整潔並避免衝突,請務必在虛擬環境中工作。這是任何嚴肅 Python 專案不可或缺的最佳實踐。

以下是如何在您的終端機中進行設定:

  1. 建立虛擬環境:

    # On macOS/Linux
    python3 -m venv pdf_env
    
    # On Windows
    python -m venv pdf_env
    
  2. 啟用它:

    # On macOS/Linux
    source pdf_env/bin/activate
    
    # On Windows
    .\pdf_env\Scripts\activate
    

    您的終端機提示符現在應該顯示 (pdf_env)。

  3. 安裝函式庫: 我們將安裝所有三個我們正在比較的函式庫,以便您輕鬆進行實驗。

    pip install pypdf2 pdfplumber pymupdf
    

    這樣,您的環境就準備好執行下面的程式碼範例了。


方法 1:使用 PyPDF2 進行基本文字提取

PyPDF2 是執行基本 PDF 操作的首選函式庫。它簡單易用,存在已久,非常適合文字可選取且非圖像部分的「原生」PDF。如果您的文件是簡單的報告、文章或基於文字的匯出,PyPDF2 將以最少的程式碼完成任務。

主要限制是什麼?它讀取 PDF 的內部文字流,這不一定與視覺閱讀順序一致,尤其是在多欄版面中。它也沒有表格的概念;它只會將所有單元格文字混雜在一起。

這是一個從 PDF 提取所有文字的簡單腳本:

# requirements: pip install pypdf2

import PyPDF2

def extract_text_with_pypdf2(pdf_path):
    """
    Extracts text from a PDF file using the PyPDF2 library.

    Args:
        pdf_path (str): The file path to the PDF.

    Returns:
        str: The extracted text content, or an error message.
    """
    try:
        with open(pdf_path, 'rb') as file:
            reader = PyPDF2.PdfReader(file)
            num_pages = len(reader.pages)
            print(f"Total pages: {num_pages}")

            full_text = ""
            for page_num in range(num_pages):
                page = reader.pages[page_num]
                full_text += page.extract_text() + "\n"
        
        return full_text

    except FileNotFoundError:
        return f"Error: The file at {pdf_path} was not found."
    except Exception as e:
        return f"An unexpected error occurred: {e}"

# --- Usage Example ---
pdf_file = 'path/to/your/document.pdf'
extracted_text = extract_text_with_pypdf2(pdf_file)

if "Error" not in extracted_text:
    print("--- Extracted Text ---")
    print(extracted_text)
else:
    print(extracted_text)

這個腳本對於簡單的單欄文字運作良好。但是當您給它一個帶有整齊表格的財務報表時會發生什麼?您會得到一堆沒有結構的文字和數字。這就是我們下一個函式庫大放異彩的地方。

方法 2:使用 pdfplumber 處理表格和版面

當您的任務涉及提取結構化資料時,pdfplumber 是正確的工具。它建立在 pdfminer.six 之上,旨在讓您精確存取 PDF 頁面的幾何結構。它「看見」字元、線條和矩形,並且具有出色的內建方法來偵測和提取表格。

這對於資料科學和業務自動化任務來說是一個遊戲規則的改變者。想像一下,嘗試從公司的 PDF 報告中提取季度收益。使用 PyPDF2,這將是字串解析的惡夢。使用 pdfplumber,您可以將資料作為一個乾淨的列表的列表獲取,準備好用於 Pandas DataFrame。

pdfplumber 在結構化資料方面優於 PyPDF2 的主要原因在於它能夠解釋視覺版面,而不僅僅是原始文字流。 它理解某些文字元素是按行和列對齊的,並由線條分隔。

以下是如何從 PDF 頁面提取表格:

# requirements: pip install pdfplumber

import pdfplumber
import pandas as pd

def extract_tables_with_pdfplumber(pdf_path, page_number=0):
    """
    Extracts all tables from a specific page of a PDF using pdfplumber.

    Args:
        pdf_path (str): The file path to the PDF.
        page_number (int): The page number to extract tables from (0-indexed).

    Returns:
        list of pandas.DataFrame: A list where each element is a DataFrame
                                  representing a table found on the page.
    """
    tables = []
    try:
        with pdfplumber.open(pdf_path) as pdf:
            if page_number >= len(pdf.pages):
                print(f"Error: Page {page_number} is out of range. The PDF has {len(pdf.pages)} pages.")
                return tables
            
            page = pdf.pages[page_number]
            # .extract_tables() is the key method here
            extracted_tables = page.extract_tables()
            
            for table_data in extracted_tables:
                # Convert the list of lists into a pandas DataFrame
                df = pd.DataFrame(table_data[1:], columns=table_data[0])
                tables.append(df)
        
        return tables

    except FileNotFoundError:
        print(f"Error: The file at {pdf_path} was not found.")
        return tables
    except Exception as e:
        print(f"An unexpected error occurred: {e}")
        return tables

# --- Usage Example ---
# You'll need pandas for this example: pip install pandas
pdf_file_with_table = 'path/to/your/report.pdf'
all_tables = extract_tables_with_pdfplumber(pdf_file_with_table, page_number=0)

if all_tables:
    print(f"Found {len(all_tables)} table(s) on page 0.")
    for i, table_df in enumerate(all_tables):
        print(f"\n--- Table {i+1} ---")
        print(table_df)
else:
    print("No tables found on the specified page.")

這種精確度的代價是速度。pdfplumber 在分析頁面方面做了更多工作,因此它本質上比那些只傾倒文字的函式庫慢。

方法 3:使用 PyMuPDF (Fitz) 進行高效能提取

當您需要快速處理數百或數千個 PDF 時,效能成為決定性因素。這正是 PyMuPDF(您將其匯入為 fitz)佔主導地位的地方。它是 MuPDF(一個輕量級 C 函式庫)的 Python 綁定,這使其速度極快。

我曾經有一個專案需要處理數千份多頁法律文件。我最初的 pdfplumber 腳本預計需要數小時。切換到 PyMuPDF 後,運行時間縮短到 30 分鐘以下。速度差異就是如此巨大。

除了速度之外,PyMuPDF 還是功能強大的工具。它可以將頁面渲染為圖像(對於 OCR 工作流程至關重要)、提取嵌入圖像並處理註釋。雖然它的表格提取功能不如 pdfplumber 那樣開箱即用,但其原始文字提取速度是無與倫比的。

這是 PyMuPDF 快速文字提取的等效方法:

# requirements: pip install PyMuPDF

import fitz  # The PyMuPDF library

def extract_text_with_pymupdf(pdf_path):
    """
    Extracts text from a PDF file using the high-performance PyMuPDF (Fitz) library.

    Args:
        pdf_path (str): The file path to the PDF.

    Returns:
        str: The extracted text content, or an error message.
    """
    try:
        doc = fitz.open(pdf_path)
        full_text = ""
        for page in doc:
            # .get_text() is the core function
            full_text += page.get_text() + "\n"
        
        doc.close()
        return full_text

    except FileNotFoundError:
        return f"Error: The file at {pdf_path} was not found."
    except Exception as e:
        # PyMuPDF can raise specific errors, e.g., fitz.fitz.FitzError
        return f"An error occurred with PyMuPDF: {e}"

# --- Usage Example ---
pdf_file = 'path/to/your/document.pdf'
fast_extracted_text = extract_text_with_pymupdf(pdf_file)

if "Error" not in fast_extracted_text:
    print("--- Extracted Text (Fast Method) ---")
    print(fast_extracted_text)
else:
    print(fast_extracted_text)

對於基於文字的 PDF 的純粹吞吐量而言,PyMuPDF 是無可爭議的冠軍。


特殊情況:使用 OCR 處理掃描 PDF

您可能會想:如果這些方法都不起作用會發生什麼?如果您在掃描文件(例如合約圖片或數位化書頁)上運行上述程式碼,您將得到一個空字串。

發生這種情況是因為沒有文字層。PDF 包含的是圖像,而不是字元。為了解決這個問題,您需要光學字元辨識 (OCR) 來「讀取」圖像並將其轉換為機器可讀的文字。

標準的 Python 解決方案是 pytesseract,它是 Google Tesseract OCR 引擎的包裝器。雖然功能強大,但它帶來了一個主要麻煩:您必須在系統上單獨安裝 Tesseract(例如,在 Mac 上透過 brew 或在 Windows 上透過安裝程式),並確保 Python 可以找到可執行檔。這種設定可能很脆弱,尤其是在將程式碼部署到伺服器或與同事共享時。

替代方案:使用無程式碼工具預處理複雜 PDF

當您時間緊迫或只是不想處理 OCR 依賴項的麻煩時,一個實用的替代方案是首先將文字提取卸載到專用工具。這將複雜的 OCR 問題與您的核心 Python 邏輯分開。

像 Lynote AI PDF 文字提取器 這樣的 AI 驅動工具可以作為強大的預處理器。您可以上傳您難以處理的掃描 PDF,它將在幕後處理 OCR,為您提供乾淨的文字,然後您可以將其輸入到您的腳本中。這對於一次性任務或處理少量有問題的文件特別有用。

以下是工作流程的簡單程度:

  1. 上傳您的 PDF 檔案。 導航到 Lynote 工作區。在「上傳檔案」選項卡中,您可以拖放您的 PDF 或瀏覽您的電腦來選擇它。這適用於基於文字和基於掃描圖像的 PDF。
  2. 從 PDF 提取文字。 檔案上傳後,點擊「建立筆記」按鈕。Lynote 的 AI 引擎會處理文件,如果偵測到基於圖像的檔案,會自動應用 OCR,並生成一個乾淨、可搜尋的文字版本。
  3. 複製提取的文字。 一旦文字出現在編輯器中,您可以審閱它,進行任何微小的更正,然後使用複製按鈕抓取整個內容。它現在已在您的剪貼簿中,準備好作為字串變數貼入您的 Python 腳本。

file-upload.jpg

extract-pdf-text.jpg

這種方法讓您可以專注於程式碼的資料分析部分,而不是本地 OCR 設定的基礎設施和錯誤處理。

常見陷阱和進階技巧

從 PDF 提取文字很少是一個完美的過程。以下是一些您可能會遇到的常見問題:

  • 字元編碼: 您可能會遇到 UnicodeDecodeError。這通常發生在較舊的 PDF 或由不常見軟體生成的 PDF 上。大多數現代函式庫都能很好地處理 UTF-8,但如果函式庫允許,指定編碼有時會有幫助。
  • 受密碼保護的 PDF: 如果 PDF 需要密碼才能打開,所有這些函式庫都將失敗。您必須在打開過程中提供密碼。例如,PyPDF2.PdfReader(file, password='your_password')。
  • 格式遺失: 請記住,文字提取幾乎總是會遺失粗體、斜體、字體大小和顏色等格式。您獲得的是原始文字內容,而不是視覺呈現。
  • 欄位文字混亂: 如 PyPDF2 所述,多欄版面(如學術論文中)可能會導致文字混雜來自不同欄位的行。pdfplumber 在分離這些方面做得更好,因為它理解頁面的幾何結構。

專家建議: 始終在您的文件代表性樣本上測試您的腳本。在一個 PDF 上完美運作的解決方案,可能在來自不同來源的另一個 PDF 上完全失敗。

常見問題

為什麼我從表格中提取的文字變成了一長串混亂的字串?

這是像 PyPDF2 這樣不分析頁面版面的函式庫的典型失敗模式。它們按照檔案中儲存的順序讀取原始文字流,這通常與視覺上的行和列結構不符。要解決這個問題,您必須使用像 **pdfplumber** 這樣具有版面感知能力的函式庫,它專門設計用於識別表格資料。

Python 可以從 PDF 頁面的特定區域提取文字嗎?

是的,但您需要一個提供座標資訊的函式庫。pdfplumber 和 PyMuPDF 在這方面表現出色。使用 pdfplumber,您可以使用 .crop((x0, top, x1, bottom)) 方法建立一個邊界框,然後只在該裁剪區域內運行 .extract_text() 或 .extract_tables()。

為什麼我的掃描 PDF 提取的文字是空的?

您的 PDF 包含的是文字圖像,而不是實際的文字資料。標準函式庫無法「讀取」圖像。您需要使用光學字元辨識 (OCR) 過程。您可以設定一個帶有 pytesseract 的本地 OCR 引擎,或者先使用像 Lynote 這樣的預處理工具將基於圖像的 PDF 轉換為乾淨的文字。

我如何處理多語言 PDF?

像 PyMuPDF 和 pdfplumber 這樣的現代函式庫通常能很好地處理 Unicode(支援大多數語言)。主要挑戰出現在 OCR 過程中。例如,Tesseract 要求您下載並指定您希望它使用的語言包(例如,-l eng+fra 用於英語和法語)。

結論:選擇正確的 Python PDF 工具

在 Python 中,沒有一個「最佳」的函式庫可以從 PDF 提取文字。正確的選擇總是取決於您的文件性質和專案目標。

讓我們將其歸結為一個簡單的決策樹:

  • 如果您的 PDF 是簡單的、基於文字的文件,並且您只需要原始內容,那麼 PyPDF2 是最容易且最快實施的。
  • 如果您的 PDF 包含表格或結構化版面,您需要將其解析為資料(例如,用於載入到資料庫或 Pandas DataFrame),那麼 pdfplumber 是明顯的贏家。
  • 如果您正在處理大量文件,並且原始速度是您的首要任務,那麼 PyMuPDF (Fitz) 是最強大且效能最佳的選項。
  • 如果您正在處理掃描的、基於圖像的 PDF,您必須使用 OCR。對於無需本地設定麻煩的快速可靠解決方案,在將乾淨文字引入您的 Python 環境之前,使用外部工具預處理檔案通常是最務實的方法。
Janet L. Harris

作者:Janet L. Harris

AI寫作專家

Janet 審查 AI 偵測器和人性化工具,重點關注其準確性、限制和負責任的使用。 查看全部文章 →