最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python使用PyPDF2實現(xiàn)快速提取PDF文本

 更新時間:2026年04月07日 08:55:31   作者:無心水  
在日常辦公和數(shù)據(jù)處理中,PDF文件幾乎無處不在,本文將帶你從零開始,用PyPDF2快速提取PDF文本,涵蓋安裝配置、核心操作、元數(shù)據(jù)獲取、中文亂碼避坑等全流程,希望對大家有所幫助

前言

在日常辦公和數(shù)據(jù)處理中,PDF文件幾乎無處不在。合同、報告、論文、發(fā)票……每天都有大量PDF文檔需要處理。當我們需要從中提取文字信息時,手動復制粘貼不僅效率低下,而且容易出錯。

Python的PyPDF2庫,正是解決這一痛點的利器。它輕量、純Python實現(xiàn)、無需安裝額外依賴,是初學者入門PDF自動化處理的最佳選擇。

本文將帶你從零開始,用PyPDF2快速提取PDF文本,涵蓋安裝配置、核心操作、元數(shù)據(jù)獲取、中文亂碼避坑等全流程。全程附代碼和圖示,確保你讀完就能上手寫代碼。

一、PyPDF2 是什么?適用場景與核心優(yōu)缺點

1.1 適用場景

PyPDF2是一個純Python的PDF處理庫,能夠在不借助任何外部軟件的情況下,對PDF文件進行各種操作[reference:0]。它在以下場景中表現(xiàn)出色:

  • 批量提取PDF文本:從成百上千份報告中提取關鍵詞、摘要或全文
  • 合并/拆分PDF:將多個PDF合并為一個文檔,或?qū)⒋笮蚉DF按頁拆分
  • 讀取PDF元信息:獲取文檔的作者、標題、創(chuàng)建時間等信息
  • 加密/解密PDF:為敏感文檔添加密碼保護
  • 頁面旋轉、裁剪、添加水印等基礎頁面操作

1.2 核心優(yōu)缺點

維度評價說明
優(yōu)點輕量易上手純Python實現(xiàn),一行pip安裝,API簡潔直觀
優(yōu)點零外部依賴無需安裝Adobe Acrobat或其他PDF軟件
優(yōu)點基礎功能全覆蓋合并、拆分、提取、加密等一應俱全
缺點中文易亂碼對中文字體編碼支持較弱,這是最常見的坑
缺點文本提取能力有限對復雜排版、表格、掃描件基本失效
缺點大文件內(nèi)存占用高將整個PDF加載到內(nèi)存,幾百頁可能卡死

特別提醒:PyPDF2對中文PDF提取文本時容易產(chǎn)生亂碼。官方原版PyPDF2已停止維護,推薦使用其現(xiàn)代分支 pypdf(API幾乎完全兼容)[reference:1]。下文代碼同時支持兩種寫法,你只需將 import PyPDF2 替換為 import pypdf 即可平滑遷移。

1.3 與其他PDF處理庫的對比

為了讓讀者更清楚PyPDF2的定位,下圖展示了主流Python PDF庫的對比:

一句話選擇建議:日?;A操作用PyPDF2/pypdf;提取中文或表格換pdfplumber;追求性能或處理大型PDF用PyMuPDF;掃描件PDF直接上OCR。

二、環(huán)境準備:pip安裝 + 虛擬環(huán)境配置

2.1 基礎安裝

打開終端/命令提示符,執(zhí)行以下命令:

pip install PyPDF2

如果你決定使用現(xiàn)代分支pypdf(強烈推薦),執(zhí)行:

pip install pypdf

驗證安裝是否成功:

python -c "import PyPDF2; print(PyPDF2.__version__)"
# 輸出類似:3.0.0

2.2 虛擬環(huán)境配置(團隊項目推薦)

# 創(chuàng)建虛擬環(huán)境
python -m venv pdf_env
# 激活虛擬環(huán)境(Windows)
pdf_env\Scripts\activate
# 激活虛擬環(huán)境(Mac/Linux)
source pdf_env/bin/activate
# 在虛擬環(huán)境中安裝
pip install PyPDF2
# 導出依賴清單
pip freeze > requirements.txt

2.3 安裝常見問題

錯誤信息原因解決方案
No module named 'PyPDF2'未安裝庫執(zhí)行 pip install PyPDF2
ImportError: cannot import name 'PdfFileReader'新版API變更改用 from PyPDF2 import PdfReader
pip install 超時網(wǎng)絡問題換國內(nèi)鏡像:pip install PyPDF2 -i https://pypi.tuna.tsinghua.edu.cn/simple

三、核心操作:逐頁讀取PDF文本

3.1 初學者最易犯的錯誤

很多新手會這樣寫:

import PyPDF2
with open('example.pdf', 'rb') as file:
    reader = PyPDF2.PdfReader(file)
    print(reader)  # 輸出:<PyPDF2._reader.PdfReader object at 0x...>

打印出來的只是一個內(nèi)存地址,而不是PDF的內(nèi)容[reference:2]。這是因為PdfReader對象代表的是整個PDF文檔的結構,而不是文本本身。

3.2 逐頁提取完整代碼

import PyPDF2

def extract_text_from_pdf(pdf_path):
    """從PDF文件中提取所有文本并打印"""
    try:
        with open(pdf_path, 'rb') as file:
            reader = PyPDF2.PdfReader(file)
            print(f"文件共 {len(reader.pages)} 頁\n")
            
            for page_num, page in enumerate(reader.pages):
                text = page.extract_text()
                print(f"--- 第 {page_num + 1} 頁 ---")
                print(text if text else "[該頁無文本或提取失敗]")
                print()
                
    except FileNotFoundError:
        print(f"錯誤:文件 '{pdf_path}' 不存在")
    except Exception as e:
        print(f"處理PDF時發(fā)生錯誤:{e}")

# 使用示例
extract_text_from_pdf('example.pdf')

3.3 只提取指定頁面

# 只提取第3頁(索引從0開始,所以第3頁的索引是2)
reader = PyPDF2.PdfReader('example.pdf')
third_page_text = reader.pages[2].extract_text()
print(third_page_text)

3.4 合并多個PDF文件

from PyPDF2 import PdfReader, PdfWriter

def merge_pdfs(pdf_list, output_path):
    writer = PdfWriter()
    
    for pdf_file in pdf_list:
        reader = PdfReader(pdf_file)
        for page in reader.pages:
            writer.add_page(page)
    
    with open(output_path, 'wb') as f:
        writer.write(f)
    
    print(f"合并完成!共 {len(writer.pages)} 頁,保存至 {output_path}")

# 使用示例
merge_pdfs(['file1.pdf', 'file2.pdf', 'file3.pdf'], 'merged.pdf')

3.5 拆分PDF文件

from PyPDF2 import PdfReader, PdfWriter

def split_pdf(input_pdf, output_dir):
    reader = PdfReader(input_pdf)
    
    for i, page in enumerate(reader.pages):
        writer = PdfWriter()
        writer.add_page(page)
        
        output_path = f"{output_dir}/page_{i+1}.pdf"
        with open(output_path, 'wb') as f:
            writer.write(f)
    
    print(f"拆分完成!共 {len(reader.pages)} 個文件")

# 只拆分前5頁
def split_first_n_pages(input_pdf, n, output_dir):
    reader = PdfReader(input_pdf)
    writer = PdfWriter()
    
    for page in reader.pages[:n]:
        writer.add_page(page)
    
    with open(f"{output_dir}/first_{n}_pages.pdf", 'wb') as f:
        writer.write(f)

四、進階:獲取PDF元信息

PDF文件通常包含元數(shù)據(jù)(Metadata),如作者、標題、創(chuàng)建工具、加密狀態(tài)等。PyPDF2可以輕松讀取這些信息。

4.1 獲取完整元信息

from PyPDF2 import PdfReader

reader = PdfReader('example.pdf')
info = reader.metadata

print("=" * 40)
print("PDF 元信息")
print("=" * 40)
print(f"標題: {info.title}")
print(f"作者: {info.author}")
print(f"主題: {info.subject}")
print(f"創(chuàng)建者: info.creator}")
print(f"生產(chǎn)者: info.producer}")
print(f"頁數(shù): {len(reader.pages)}")
print(f"是否加密: {reader.is_encrypted}")
print("=" * 40)

4.2 處理加密PDF

from PyPDF2 import PdfReader

reader = PdfReader('encrypted.pdf')

if reader.is_encrypted:
    try:
        # 嘗試解密
        reader.decrypt('your_password')
        print("解密成功!")
        
        # 現(xiàn)在可以正常提取文本
        text = reader.pages[0].extract_text()
        print(text)
    except Exception as e:
        print(f"解密失?。簕e}")
else:
    print("文件未加密,直接讀取")

重要提示:PyPDF2對加密PDF的支持有限,僅支持舊式加密算法(RC4),不支持AES-256等現(xiàn)代加密方式[reference:3]。遇到 NotImplementedError: only algorithm code 1 and 2 are supported 錯誤時,說明文件使用了不支持的加密算法,建議換用pikepdf處理[reference:4]。

五、避坑指南:中文亂碼的根源與解決方案

這是初學者在使用PyPDF2時最常踩的坑,值得花一整節(jié)來講清楚。

5.1 亂碼現(xiàn)象長什么樣?

# 原本應該是:"這是一份中文PDF文檔"
# 實際輸出:
"??è????????PDF??£"
# 或者輸出:
"?????????"

5.2 中文亂碼的根源(重點理解)

亂碼的根本原因并不復雜。下圖清晰解釋了為什么PyPDF2會提取出亂碼:

簡單來說:PDF中的中文字符存儲的是一串“編號”,需要借助“編碼映射表”才能翻譯成正確的中文。PyPDF2恰恰缺少這個翻譯能力,遇到非標準編碼的中文字體就直接“放棄治療”,輸出占位符[reference:5]。

具體來說,亂碼的根源有以下幾種:

  • 字體未嵌入或嵌入不全:PDF使用外部字體,提取時找不到對應關系
  • 編碼映射表(ToUnicode CMap)缺失:字符代碼無法映射到Unicode
  • PyPDF2本身不支持復雜字體解碼:遇到CID字體、自定義編碼的中文字體時直接輸出亂碼[reference:6]
  • 編碼方式不匹配:PDF實際使用GBK編碼,而庫默認按UTF-8解碼

5.3 如何判斷PDF是否“可提取”?

在執(zhí)行代碼之前,建議先手動測試一下PDF的文字是否可選:

from PyPDF2 import PdfReader

def check_pdf_extractability(pdf_path):
    reader = PdfReader(pdf_path)
    
    print(f"文件名: {pdf_path}")
    print(f"頁數(shù): {len(reader.pages)}")
    print(f"是否加密: {reader.is_encrypted}")
    
    # 嘗試提取第一頁的前200個字符
    sample = reader.pages[0].extract_text()[:200]
    print(f"第一頁預覽: {sample}")
    
    # 檢查生產(chǎn)者信息
    producer = reader.metadata.get('/Producer', '未知')
    print(f"生產(chǎn)者: {producer}")
    
    # 初步判斷
    if any(ord(c) > 127 for c in sample if c):
        print(">>> 可能包含非ASCII字符(中文),提取結果可能存在亂碼風險")
    else:
        print(">>> 僅包含ASCII字符,提取相對可靠")

check_pdf_extractability('test.pdf')

5.4 中文亂碼的臨時解決方案

雖然PyPDF2無法完美解決中文亂碼,但在某些場景下可以通過以下方式緩解:

方案1:使用pdfplumber替代(推薦)

# pip install pdfplumber
import pdfplumber

with pdfplumber.open('chinese_doc.pdf') as pdf:
    for page in pdf.pages:
        text = page.extract_text()
        print(text)

pdfplumber基于PDFMiner,對中文字體支持更穩(wěn)定,API也非常相似[reference:7]。

方案2:使用pypdf(現(xiàn)代分支)加容錯參數(shù)

from pypdf import PdfReader

# 添加strict=False忽略部分解析警告
reader = PdfReader('chinese_doc.pdf', strict=False)
text = reader.pages[0].extract_text()

方案3:處理掃描件PDF(圖片型PDF)

# 圖片型PDF需要先轉換為圖片,再用OCR識別
# pip install pdf2image pytesseract pillow
from pdf2image import convert_from_path
import pytesseract

images = convert_from_path('scanned.pdf')
text = pytesseract.image_to_string(images[0], lang='chi_sim')
print(text)

方案4:編碼后處理

# 嘗試手動修復編碼(僅適用于特定場景)
def fix_encoding(broken_text):
    # 嘗試不同的編碼方式
    for encoding in ['gbk', 'gb2312', 'big5', 'utf-8']:
        try:
            return broken_text.encode('latin1').decode(encoding)
        except:
            continue
    return broken_text

text = page.extract_text()
fixed_text = fix_encoding(text)

5.5 避坑總結

問題類型表現(xiàn)解決方案
文字型PDF輸出亂碼(如䏿‡)換用pdfplumber
掃描件PDF提取為空或全是亂碼走OCR路線
加密PDF報NotImplementedError換pikepdf解密
大文件內(nèi)存暴漲/卡死分批處理或換pypdf

六、完整可運行代碼:批量處理文件夾內(nèi)所有PDF

以下是一個生產(chǎn)環(huán)境可直接使用的腳本,一鍵提取文件夾內(nèi)所有PDF的文本內(nèi)容,并保存為獨立的TXT文件。

import os
import sys
from pathlib import Path
from PyPDF2 import PdfReader

def extract_text_from_pdf(pdf_path):
    """
    從單個PDF文件提取文本
    返回: (是否成功, 文本內(nèi)容)
    """
    try:
        reader = PdfReader(pdf_path)
        full_text = []
        
        for page_num, page in enumerate(reader.pages, 1):
            text = page.extract_text()
            if text:
                full_text.append(f"[第{page_num}頁]\n{text}\n")
            else:
                full_text.append(f"[第{page_num}頁]\n[無文本或提取失敗]\n")
        
        return True, "\n".join(full_text)
    
    except Exception as e:
        return False, f"處理失?。簕str(e)}"

def batch_extract_pdfs(input_folder, output_folder, extensions=None):
    """
    批量提取文件夾內(nèi)所有PDF的文本
    
    參數(shù):
        input_folder: 存放PDF文件的文件夾路徑
        output_folder: 輸出TXT文件的文件夾路徑
        extensions: 文件擴展名列表,默認為['.pdf']
    """
    if extensions is None:
        extensions = ['.pdf', '.PDF']
    
    # 創(chuàng)建輸出文件夾
    Path(output_folder).mkdir(parents=True, exist_ok=True)
    
    # 收集所有PDF文件
    pdf_files = []
    for ext in extensions:
        pdf_files.extend(Path(input_folder).glob(f"*{ext}"))
    
    if not pdf_files:
        print(f"在文件夾 '{input_folder}' 中未找到PDF文件")
        return
    
    print(f"共找到 {len(pdf_files)} 個PDF文件,開始處理...\n")
    
    success_count = 0
    fail_count = 0
    
    for pdf_file in pdf_files:
        print(f"正在處理: {pdf_file.name} ...")
        
        success, content = extract_text_from_pdf(str(pdf_file))
        
        output_path = Path(output_folder) / f"{pdf_file.stem}.txt"
        
        with open(output_path, 'w', encoding='utf-8') as f:
            f.write(content)
        
        if success:
            success_count += 1
            print(f"  ? 成功,已保存至: {output_path.name}")
        else:
            fail_count += 1
            print(f"  ? 失敗: {content[:100]}")
    
    print(f"\n{'='*50}")
    print(f"處理完成!成功: {success_count},失敗: {fail_count}")
    print(f"輸出目錄: {output_folder}")
    print(f"{'='*50}")

def extract_with_progress(input_folder, output_folder, show_preview=True):
    """
    帶進度預覽的批量提取功能
    """
    pdf_files = list(Path(input_folder).glob("*.pdf")) + list(Path(input_folder).glob("*.PDF"))
    total = len(pdf_files)
    
    for idx, pdf_file in enumerate(pdf_files, 1):
        print(f"[{idx}/{total}] 處理: {pdf_file.name}")
        
        success, content = extract_text_from_pdf(str(pdf_file))
        
        if show_preview and success:
            preview = content[:200].replace('\n', ' ')
            print(f"  預覽: {preview}...")
        
        output_path = Path(output_folder) / f"{pdf_file.stem}.txt"
        with open(output_path, 'w', encoding='utf-8') as f:
            f.write(content)
        
        print(f"  ? 已保存\n")

if __name__ == "__main__":
    # 方式1:直接運行
    INPUT_DIR = "./pdfs"      # 存放PDF的文件夾
    OUTPUT_DIR = "./output"   # 輸出TXT的文件夾
    
    # 方式2:命令行傳參
    if len(sys.argv) >= 3:
        INPUT_DIR = sys.argv[1]
        OUTPUT_DIR = sys.argv[2]
    
    batch_extract_pdfs(INPUT_DIR, OUTPUT_DIR)
    
    # 如果需要更詳細的處理進度,使用以下函數(shù)
    # extract_with_progress(INPUT_DIR, OUTPUT_DIR, show_preview=True)

七、總結與延伸建議

7.1 本文核心要點回顧

知識點關鍵內(nèi)容
安裝配置pip install PyPDF2,推薦同時安裝pdfplumber作為備選
文本提取三步走:PdfReaderpages.extract_text()
合并/拆分使用PdfWriter添加/寫入頁面
元數(shù)據(jù)reader.metadata獲取標題、作者等信息
中文亂碼根源在于字體編碼映射缺失,推薦pdfplumber替代

7.2 PyPDF2 vs pypdf 版本選擇建議

版本維護狀態(tài)推薦度適用場景
PyPDF2 1.x~2.x已停止?不推薦
PyPDF2 3.x最終版??短期使用
pypdf活躍更新?????強烈推薦

只需將 import PyPDF2 改為 import pypdf,from PyPDF2 import xxx 改為 from pypdf import xxx,代碼幾乎無需其他改動即可平滑遷移。

7.3 進階學習方向

  • pdfplumber:提取中文PDF文本、表格數(shù)據(jù)的首選替代方案
  • PyMuPDF:追求極致性能時使用,速度遠超PyPDF2
  • pikepdf:處理加密PDF、優(yōu)化合并后體積時使用
  • PaddleOCR:處理掃描件PDF時使用,中英文識別準確率高

一點提醒:任何工具都有其邊界。PyPDF2最適合處理西文、無加密、文本型PDF的輕量級操作。遇到中文亂碼、掃描件、大文件等場景,及時切換工具往往比“硬扛”更高效。

到此這篇關于Python使用PyPDF2實現(xiàn)快速提取PDF文本的文章就介紹到這了,更多相關Python PyPDF2提取PDF文本內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • 使用Python完成15位18位身份證的互轉功能

    使用Python完成15位18位身份證的互轉功能

    這篇文章主要介紹了使用Python完成15位18位身份證的互轉功能,本文給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-11-11
  • opencv-python 提取sift特征并匹配的實例

    opencv-python 提取sift特征并匹配的實例

    今天小編就為大家分享一篇opencv-python 提取sift特征并匹配的實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-12-12
  • python?離散點圖畫法的實現(xiàn)

    python?離散點圖畫法的實現(xiàn)

    本文主要介紹了python?離散點圖畫法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-04-04
  • Python filter()及reduce()函數(shù)使用方法解析

    Python filter()及reduce()函數(shù)使用方法解析

    這篇文章主要介紹了Python filter()及reduce()函數(shù)使用方法解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-09-09
  • Python對象轉換為json的方法步驟

    Python對象轉換為json的方法步驟

    這篇文章主要介紹了Python對象轉換為json的方法步驟,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-04-04
  • Django Aggregation聚合使用方法解析

    Django Aggregation聚合使用方法解析

    這篇文章主要介紹了Django Aggregation聚合使用方法解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-08-08
  • 利用Python監(jiān)控設備電池電量并發(fā)送通知

    利用Python監(jiān)控設備電池電量并發(fā)送通知

    在日常使用電子設備時,及時了解電池電量狀態(tài)并進行合理充電是非常重要的,本文將使用Python進行設備電池電量的監(jiān)控并發(fā)送通知,有需要的可以了解下
    2025-03-03
  • 將python文件打包成EXE應用程序的方法

    將python文件打包成EXE應用程序的方法

    相信大家都想把自己完成的項目打包成EXE應用文件,然后就可以放在桌面隨時都能運行了,下面來分享利用pytinstaller這個第三方庫來打包程序,感興趣的朋友跟隨小編一起看看吧
    2019-05-05
  • 利用Python封裝MySQLHelper類實現(xiàn)數(shù)據(jù)庫的增刪改查功能

    利用Python封裝MySQLHelper類實現(xiàn)數(shù)據(jù)庫的增刪改查功能

    Python 連接 MySQL 的方法有很多,常用的有 pymysql 和 mysql-connector-python 兩種庫,本文主要介紹了如何封裝一個MySQLHelper類,實現(xiàn)對數(shù)據(jù)庫的增刪改查功能,感興趣的可以了解一下
    2023-06-06
  • Python抓取京東圖書評論數(shù)據(jù)

    Python抓取京東圖書評論數(shù)據(jù)

    最近接了個項目,需要抓取京東圖書的評論,把代碼放出來給大家分享下,希望能有所幫助
    2014-08-08

最新評論

正安县| 阜阳市| 沂水县| 青河县| 秦安县| 齐齐哈尔市| 凭祥市| 汶上县| 资中县| 镇江市| 恩施市| 班玛县| 彩票| 南阳市| 铜川市| 北安市| 安福县| 淳化县| 岗巴县| 吉林市| 龙南县| 景宁| 浦东新区| 苍梧县| 皋兰县| 桐梓县| 汉寿县| 纳雍县| 吉首市| 马公市| 衡阳县| 屏山县| 福清市| 德昌县| 庆元县| 怀化市| 濮阳市| 明溪县| 开阳县| 宁强县| 乌兰浩特市|