Cách trích xuất văn bản từ PDF bằng Python (So sánh 3 thư viện)
Việc trích xuất văn bản từ PDF nghe có vẻ đơn giản, nhưng bất kỳ nhà phát triển nào đã từng thử đều biết rằng đây là một lĩnh vực đầy rẫy các ngoại lệ, bố cục bị hỏng và các tài liệu cứng đầu, dựa trên hình ảnh. Hướng dẫn này sẽ giúp bạn vượt qua những khó khăn đó. Chúng ta sẽ bắt đầu với việc so sánh trực tiếp các thư viện Python tốt nhất cho công việc này, để bạn có thể chọn ngay công cụ phù hợp cho dự án của mình.

Sau đó, chúng ta sẽ xem xét các ví dụ mã cho ba thư viện hiệu quả nhất—PyPDF2, pdfplumber và PyMuPDF (Fitz)—bao gồm mọi thứ từ việc trích xuất văn bản cơ bản đến xử lý các bảng phức tạp. Chúng ta cũng sẽ giải quyết thách thức khó khăn nhất: các tệp PDF được quét yêu cầu Nhận dạng Ký tự Quang học (OCR), và chỉ cho bạn một cách thực tế để xử lý chúng mà không cần thiết lập cục bộ phức tạp. Cuối cùng, bạn sẽ có mã và chiến lược để tự động hóa quy trình xử lý PDF của mình một cách đáng tin cậy.
Đánh giá nhanh: Các thư viện Python tốt nhất để trích xuất văn bản từ PDF
Trước khi chúng ta đi sâu vào mã, đây là cái nhìn tổng quan về các ứng cử viên hàng đầu. Lựa chọn của bạn sẽ hoàn toàn phụ thuộc vào việc bạn cần tốc độ, sự đơn giản hay phân tích bố cục chính xác.
| Thư viện | Tốt nhất cho | Xử lý bố cục/bảng | Hiệu suất | Dễ sử dụng (1-5) |
|---|---|---|---|---|
| PyPDF2 | Tài liệu đơn giản, chỉ có văn bản; thao tác PDF cơ bản (ghép/tách) | Kém (trích xuất luồng văn bản, không có dữ liệu vị trí) | Trung bình | 5 |
| pdfplumber | Trích xuất dữ liệu từ bảng; tài liệu có bố cục cấu trúc | Tuyệt vời (cung cấp tọa độ cho văn bản, đường kẻ và hình chữ nhật) | Chậm hơn | 4 |
| PyMuPDF (Fitz) | Xử lý hàng loạt tốc độ cao; xử lý hình ảnh và chú thích | Tốt (có thể trích xuất văn bản với thông tin vị trí cơ bản) | Tuyệt vời (nhanh nhất) | 4 |
Tóm lại: Bắt đầu với PyPDF2 cho các trường hợp đơn giản nhất. Chuyển sang pdfplumber ngay khi bạn thấy một bảng. Chọn PyMuPDF khi hiệu suất là mối quan tâm hàng đầu của bạn.
Trước khi bắt đầu: Thiết lập môi trường Python của bạn
Để giữ cho các phụ thuộc của dự án của bạn sạch sẽ và tránh xung đột, hãy luôn làm việc trong một môi trường ảo. Đây là một thực hành tốt nhất không thể bỏ qua cho bất kỳ dự án Python nghiêm túc nào.
Đây là cách thiết lập trong terminal của bạn:
-
Tạo môi trường ảo:
# On macOS/Linux python3 -m venv pdf_env # On Windows python -m venv pdf_env -
Kích hoạt nó:
# On macOS/Linux source pdf_env/bin/activate # On Windows .\pdf_env\Scripts\activateDấu nhắc terminal của bạn bây giờ sẽ hiển thị
(pdf_env). -
Cài đặt các thư viện: Chúng ta sẽ cài đặt cả ba thư viện đang so sánh để bạn có thể dễ dàng thử nghiệm.
pip install pypdf2 pdfplumber pymupdfVới những bước đó, môi trường của bạn đã sẵn sàng cho các ví dụ mã dưới đây.
Phương pháp 1: Trích xuất văn bản cơ bản với PyPDF2
PyPDF2 là thư viện được lựa chọn cho các thao tác PDF cơ bản. Nó đơn giản, đã tồn tại từ lâu và hoàn hảo cho các tệp PDF "gốc" nơi văn bản có thể chọn được và không phải là một phần của hình ảnh. Nếu tài liệu của bạn là các báo cáo, bài viết đơn giản hoặc xuất văn bản, PyPDF2 sẽ hoàn thành công việc với ít mã nhất.
Hạn chế chính? Nó đọc luồng văn bản nội bộ của PDF, không phải lúc nào cũng tương ứng với thứ tự đọc trực quan, đặc biệt là trong các bố cục nhiều cột. Nó cũng không có khái niệm về bảng; nó sẽ chỉ ghép tất cả văn bản ô lại với nhau.
Đây là một đoạn mã đơn giản để trích xuất tất cả văn bản từ một tệp 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)
Đoạn mã này hoạt động rất tốt cho văn bản đơn giản, một cột. Nhưng điều gì sẽ xảy ra khi bạn cung cấp cho nó một báo cáo tài chính với các bảng gọn gàng? Bạn sẽ nhận được một mớ văn bản và số liệu lộn xộn không có cấu trúc. Đó là lúc thư viện tiếp theo của chúng ta phát huy tác dụng.
Phương pháp 2: Xử lý bảng và bố cục với pdfplumber
Khi nhiệm vụ của bạn liên quan đến việc trích xuất dữ liệu có cấu trúc, pdfplumber là công cụ phù hợp. Được xây dựng dựa trên pdfminer.six, nó được thiết kế để cung cấp cho bạn quyền truy cập chi tiết vào hình học của một trang PDF. Nó "nhìn thấy" các ký tự, đường kẻ và hình chữ nhật, và nó có một phương pháp tích hợp tuyệt vời để phát hiện và trích xuất bảng.
Đây là một yếu tố thay đổi cuộc chơi cho các tác vụ khoa học dữ liệu và tự động hóa kinh doanh. Hãy tưởng tượng việc cố gắng lấy thu nhập hàng quý từ báo cáo PDF của một công ty. Với PyPDF2, đó là một cơn ác mộng của việc phân tích chuỗi. Với pdfplumber, bạn có thể lấy dữ liệu dưới dạng một danh sách các danh sách sạch sẽ, sẵn sàng cho một Pandas DataFrame.
Lý do chính khiến pdfplumber vượt trội hơn PyPDF2 đối với dữ liệu có cấu trúc là khả năng diễn giải bố cục trực quan, chứ không chỉ là luồng văn bản thô. Nó hiểu rằng các yếu tố văn bản nhất định được căn chỉnh theo hàng và cột, được phân tách bằng các đường kẻ.
Đây là cách trích xuất bảng từ một trang 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.")
Đánh đổi cho độ chính xác này là tốc độ. pdfplumber thực hiện nhiều công việc phân tích trang hơn, vì vậy nó vốn dĩ chậm hơn các thư viện chỉ xuất văn bản.
Phương pháp 3: Trích xuất hiệu suất cao với PyMuPDF (Fitz)
Khi bạn cần xử lý hàng trăm hoặc hàng nghìn tệp PDF một cách nhanh chóng, hiệu suất trở thành yếu tố quyết định. Đây là lúc PyMuPDF, mà bạn nhập dưới dạng fitz, chiếm ưu thế. Nó là một liên kết Python cho MuPDF, một thư viện C nhẹ, giúp nó cực kỳ nhanh.
Tôi từng có một dự án yêu cầu xử lý vài nghìn tài liệu pháp lý nhiều trang. Đoạn mã pdfplumber ban đầu của tôi được dự kiến sẽ mất hàng giờ. Chuyển sang PyMuPDF đã giảm thời gian chạy xuống dưới 30 phút. Sự khác biệt về tốc độ là rất đáng kể.
Ngoài tốc độ, PyMuPDF là một kho tàng tính năng. Nó có thể hiển thị các trang dưới dạng hình ảnh (quan trọng cho quy trình OCR), trích xuất hình ảnh nhúng và xử lý chú thích. Mặc dù khả năng trích xuất bảng của nó không tiện lợi như pdfplumber, nhưng tốc độ trích xuất văn bản thô của nó là không thể sánh bằng.
Đây là đoạn mã tương đương của PyMuPDF để trích xuất văn bản nhanh:
# 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)
Đối với thông lượng tuyệt đối trên các tệp PDF dựa trên văn bản, PyMuPDF là nhà vô địch không thể tranh cãi.
Trường hợp đặc biệt: Xử lý PDF được quét bằng OCR
Bạn có thể tự hỏi: điều gì sẽ xảy ra khi không có phương pháp nào trong số này hoạt động? Nếu bạn chạy đoạn mã trên trên một tài liệu được quét—như hình ảnh của một hợp đồng hoặc một trang sách được số hóa—bạn sẽ nhận được một chuỗi rỗng.
Điều này xảy ra vì không có lớp văn bản. Tệp PDF chứa một hình ảnh, không phải ký tự. Để giải quyết vấn đề này, bạn cần sử dụng Nhận dạng Ký tự Quang học (OCR) để "đọc" hình ảnh và chuyển đổi nó thành văn bản có thể đọc được bằng máy.
Giải pháp Python tiêu chuẩn là pytesseract, một trình bao bọc cho công cụ Tesseract OCR của Google. Mặc dù mạnh mẽ, nhưng nó đi kèm với một vấn đề lớn: bạn phải cài đặt Tesseract riêng trên hệ thống của mình (ví dụ: thông qua brew trên Mac hoặc trình cài đặt trên Windows) và đảm bảo Python có thể tìm thấy tệp thực thi. Thiết lập này có thể dễ bị lỗi, đặc biệt khi triển khai mã của bạn lên máy chủ hoặc chia sẻ nó với đồng nghiệp.
Thay thế: Tiền xử lý PDF phức tạp bằng công cụ không mã
Khi bạn đang trong thời hạn gấp rút hoặc đơn giản là không muốn gặp rắc rối trong việc quản lý các phụ thuộc OCR, một giải pháp thay thế thực tế là chuyển việc trích xuất văn bản sang một công cụ chuyên dụng trước. Điều này tách biệt vấn đề OCR phức tạp khỏi logic Python cốt lõi của bạn.
Một công cụ hỗ trợ AI như trình trích xuất văn bản PDF Lynote AI có thể hoạt động như một bộ tiền xử lý mạnh mẽ. Bạn có thể tải lên tệp PDF được quét phức tạp của mình, và nó sẽ xử lý OCR ở hậu trường, cung cấp cho bạn văn bản sạch mà bạn có thể đưa vào tập lệnh của mình. Điều này đặc biệt hữu ích cho các tác vụ một lần hoặc khi xử lý một lô nhỏ các tệp có vấn đề.
Đây là cách quy trình làm việc đơn giản:
- Tải lên tệp PDF của bạn. Điều hướng đến không gian làm việc của Lynote. Trong tab 'Tải lên tệp', bạn có thể kéo và thả tệp PDF của mình hoặc duyệt máy tính để chọn. Điều này hoạt động cho cả tệp PDF dựa trên văn bản và tệp PDF dựa trên hình ảnh được quét.
- Trích xuất văn bản từ PDF. Sau khi tệp được tải lên, nhấp vào nút "Tạo ghi chú". Công cụ AI của Lynote xử lý tài liệu, tự động áp dụng OCR nếu nó phát hiện một tệp dựa trên hình ảnh và tạo ra một phiên bản văn bản sạch, có thể tìm kiếm được.
- Sao chép văn bản đã trích xuất. Khi văn bản xuất hiện trong trình chỉnh sửa, bạn có thể xem lại, thực hiện bất kỳ chỉnh sửa nhỏ nào, sau đó sử dụng nút sao chép để lấy toàn bộ nội dung. Nó hiện đã có trong khay nhớ tạm của bạn, sẵn sàng được dán vào tập lệnh Python của bạn dưới dạng một biến chuỗi.


Cách tiếp cận này cho phép bạn tập trung vào phần phân tích dữ liệu của mã, chứ không phải cơ sở hạ tầng và xử lý lỗi của một thiết lập OCR cục bộ.
Các lỗi thường gặp và mẹo nâng cao
Việc trích xuất văn bản từ PDF hiếm khi là một quy trình hoàn hảo. Dưới đây là một số vấn đề phổ biến mà bạn có thể gặp phải:
- Mã hóa ký tự: Bạn có thể gặp lỗi
UnicodeDecodeError. Điều này thường xảy ra với các tệp PDF cũ hơn hoặc những tệp được tạo bởi phần mềm không rõ nguồn gốc. Hầu hết các thư viện hiện đại đều xử lýUTF-8tốt, nhưng việc chỉ định mã hóa đôi khi có thể hữu ích nếu thư viện cho phép. - PDF được bảo vệ bằng mật khẩu: Nếu một tệp PDF yêu cầu mật khẩu để mở, tất cả các thư viện này sẽ thất bại. Bạn phải cung cấp mật khẩu trong quá trình mở. Ví dụ:
PyPDF2.PdfReader(file, password='your_password'). - Mất định dạng: Hãy nhớ rằng việc trích xuất văn bản hầu như luôn làm mất định dạng như in đậm, in nghiêng, kích thước phông chữ và màu sắc. Bạn đang nhận được nội dung văn bản thô, không phải là một biểu diễn trực quan.
- Văn bản lộn xộn từ các cột: Như đã đề cập với PyPDF2, các bố cục nhiều cột (như trong các bài báo khoa học) có thể dẫn đến văn bản trộn lẫn các dòng từ các cột khác nhau.
pdfplumbertốt hơn nhiều trong việc tách chúng, vì nó hiểu hình học của trang.
Lời khuyên từ chuyên gia: Luôn kiểm tra tập lệnh của bạn trên một mẫu tài liệu đại diện. Một giải pháp hoạt động hoàn hảo trên một tệp PDF có thể thất bại hoàn toàn trên một tệp khác từ một nguồn khác.
Câu hỏi thường gặp
Tại sao văn bản được trích xuất từ bảng của tôi lại biến thành một chuỗi dài, lộn xộn?
Đây là chế độ lỗi cổ điển của các thư viện như PyPDF2 không phân tích bố cục trang. Chúng đọc luồng văn bản thô theo thứ tự được lưu trữ trong tệp, thường không khớp với cấu trúc hàng và cột trực quan. Để khắc phục điều này, bạn phải sử dụng một thư viện nhận biết bố cục như **pdfplumber**, được thiết kế đặc biệt để nhận dạng dữ liệu dạng bảng.
Python có thể trích xuất văn bản từ một khu vực cụ thể của trang PDF không?
Có, nhưng bạn cần một thư viện cung cấp thông tin tọa độ. pdfplumber và PyMuPDF rất tuyệt vời cho việc này. Với pdfplumber, bạn có thể sử dụng phương thức .crop((x0, top, x1, bottom)) để tạo một hộp giới hạn và sau đó chạy .extract_text() hoặc .extract_tables() chỉ trong khu vực đã cắt đó.
Tại sao văn bản được trích xuất từ PDF được quét của tôi lại trống?
Tệp PDF của bạn chứa hình ảnh văn bản, không phải dữ liệu văn bản thực tế. Các thư viện tiêu chuẩn không thể "đọc" hình ảnh. Bạn cần sử dụng quy trình Nhận dạng Ký tự Quang học (OCR). Bạn có thể thiết lập một công cụ OCR cục bộ với pytesseract hoặc sử dụng một công cụ tiền xử lý như Lynote để chuyển đổi tệp PDF dựa trên hình ảnh thành văn bản sạch trước.
Làm cách nào để xử lý các tệp PDF có nhiều ngôn ngữ?
Các thư viện hiện đại như PyMuPDF và pdfplumber thường xử lý Unicode (hỗ trợ hầu hết các ngôn ngữ) tốt. Thách thức chính đến trong quá trình OCR. Ví dụ, Tesseract yêu cầu bạn tải xuống và chỉ định các gói ngôn ngữ mà bạn muốn nó sử dụng (ví dụ: -l eng+fra cho tiếng Anh và tiếng Pháp).
Kết luận: Chọn công cụ Python PDF phù hợp
Không có một thư viện "tốt nhất" duy nhất để trích xuất văn bản từ PDF trong Python. Lựa chọn đúng đắn luôn được quyết định bởi bản chất tài liệu của bạn và mục tiêu dự án của bạn.
Hãy tóm gọn lại thành một cây quyết định đơn giản:
- Nếu các tệp PDF của bạn là tài liệu đơn giản, dựa trên văn bản và bạn chỉ cần nội dung thô, PyPDF2 là cách dễ nhất và nhanh nhất để triển khai.
- Nếu các tệp PDF của bạn chứa bảng hoặc bố cục có cấu trúc mà bạn cần phân tích thành dữ liệu (ví dụ: để tải vào cơ sở dữ liệu hoặc Pandas DataFrame), pdfplumber là lựa chọn chiến thắng rõ ràng.
- Nếu bạn đang xử lý một lượng lớn tài liệu và tốc độ thô là ưu tiên hàng đầu của bạn, PyMuPDF (Fitz) là tùy chọn mạnh mẽ và hiệu quả nhất.
- Nếu bạn đang xử lý các tệp PDF được quét, dựa trên hình ảnh, bạn phải sử dụng OCR. Để có một giải pháp nhanh chóng và đáng tin cậy mà không gặp rắc rối về thiết lập cục bộ, việc tiền xử lý tệp bằng một công cụ bên ngoài thường là con đường thực tế nhất trước khi đưa văn bản sạch vào môi trường Python của bạn.
Viết bởi Janet L. Harris
Chuyên gia Viết AI
Janet đánh giá các công cụ phát hiện và nhân hóa AI, tập trung vào độ chính xác, giới hạn và cách sử dụng có trách nhiệm. Xem mọi bài viết →


