目錄標題
- 一. 通過 pdfplumber.open() 解析復雜PDF:
- 1-2. 報錯:
- V2 :
- 1-3. v3 使用tk 庫,彈框選擇文件
- 運行環境準備
- 完整代碼保存
- 運行測試步驟
- 方式二:命令行方式(適用于自動化)
- 測試用例示例
- 常見問題排查
- 1. 無文件選擇對話框彈出:
- 2. No such file or directory錯誤:
- 3. 提取內容為空:
- 4. 內存不足錯誤:
- 擴展測試建議
- 1-10 總結:
- 二. PDF中包含表格,table = first_page.extract_table() 只能提取到 PDF文件中的表頭如下:
- 1. 表格結構識別問題
- 解決辦法
- 2. 文本布局問題
- 解決辦法
- 3. 字體和顏色問題
- 解決辦法
一. 通過 pdfplumber.open() 解析復雜PDF:
這段 Python 代碼使用了 pdfplumber
庫來讀取 PDF 文件中的文本內容,下面是逐行解釋:
import pdfplumber
- 引入
pdfplumber
模塊,這是一個用于從 PDF 文件中提取文本、表格等內容的第三方庫。
# 打開 PDF 文件, 這里寫死了,看下面的V2版本,用彈框選擇文件
with pdfplumber.open("example.pdf") as pdf:
- 使用
pdfplumber.open()
方法打開名為"example.pdf"
的 PDF 文件。 - 使用
with
語句可以確保文件使用完后會自動關閉,避免資源泄露。
# 獲取第一頁page = pdf.pages[0]
- 獲取 PDF 文件的第一頁內容,
pdf.pages
是一個頁面對象的列表,索引從 0 開始。
# 提取文本text = page.extract_text()
- 調用
extract_text()
方法從第一頁中提取文本內容。 - 這個方法返回一個字符串,包含該頁的所有可提取文本(按照排版順序)。
print(text)
- 將提取到的文本打印出來。
1-2. 報錯:
ImportError: DLL load failed while importing _rust: 找不到指定的程序。
Traceback:
File "D:\Users\wang\PycharmProjects\github\ltkj-aiseek\seek_backend_py\ltjt_ai_seek_app\com\szkj\test_pdf\pdf_parser.py", line 2, in <module>import pdfplumber
File "D:\Users\wang\PycharmProjects\github\ltkj-aiseek\seek_backend_py\.venv\lib\site-packages\pdfplumber\__init__.py", line 15, in <module>from .pdf import PDF
File "D:\Users\wang\PycharmProjects\github\ltkj-aiseek\seek_backend_py\.venv\lib\site-packages\pdfplumber\pdf.py", line 8, in <module>from pdfminer.layout import LAParams
File "D:\Users\wang\PycharmProjects\github\ltkj-aiseek\seek_backend_py\.venv\lib\site-packages\pdfminer\layout.py", line 21, in <module>from pdfminer.pdfinterp import Color, PDFGraphicState
File "D:\Users\wang\PycharmProjects\github\ltkj-aiseek\seek_backend_py\.venv\lib\site-packages\pdfminer\pdfinterp.py", line 10, in <module>from pdfminer.pdfdevice import PDFDevice, PDFTextSeq
File "D:\Users\wang\PycharmProjects\github\ltkj-aiseek\seek_backend_py\.venv\lib\site-packages\pdfminer\pdfdevice.py", line 16, in <module>from pdfminer.pdfpage import PDFPage
File "D:\Users\wang\PycharmProjects\github\ltkj-aiseek\seek_backend_py\.venv\lib\site-packages\pdfminer\pdfpage.py", line 6, in <module>from pdfminer.pdfdocument import (
File "D:\Users\wang\PycharmProjects\github\ltkj-aiseek\seek_backend_py\.venv\lib\site-packages\pdfminer\pdfdocument.py", line 23, in <module>from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
File "D:\Users\wang\PycharmProjects\github\ltkj-aiseek\seek_backend_py\.venv\lib\site-packages\cryptography\hazmat\primitives\ciphers\__init__.py", line 11, in <module>from cryptography.hazmat.primitives.ciphers.base import (
File "D:\Users\wang\PycharmProjects\github\ltkj-aiseek\seek_backend_py\.venv\lib\site-packages\cryptography\hazmat\primitives\ciphers\base.py", line 10, in <module>from cryptography.hazmat.bindings._rust import openssl as rust_openssl
你遇到的 ImportError: DLL load failed while importing _rust: 找不到指定的程序 錯誤通常是由于缺少某些依賴項或環境配置問題導致的。以下是一些可能的解決方案:
- 確保安裝了所有必要的依賴項
確保你已經安裝了所有必要的依賴項,特別是 cryptography 和 pdfplumber。你可以使用以下命令來安裝這些庫:
pip install pdfplumber cryptography
- 安裝 Visual C++ Redistributable
有時,這個錯誤是由于缺少 Microsoft Visual C++ Redistributable 包引起的。你可以從微軟官方網站下載并安裝最新版本的 Visual C++ Redistributable for Visual Studio 2015, 2017, 2019 或 2022。
Visual C++ Redistributable for Visual Studio 2015, 2017, and 2019
Visual C++ Redistributable for Visual Studio 2022
- 檢查 Python 和 pip 的版本
確保你使用的是兼容的 Python 和 pip 版本。你可以使用以下命令來檢查和升級它們:
python --version
pip --version
pip install --upgrade pip
- 重新安裝 cryptography 庫
有時,重新安裝 cryptography 庫可以解決問題。你可以使用以下命令來卸載并重新安裝它:
pip uninstall cryptography
pip install cryptography
如果都安裝了,還是報錯,那就是python版本的問題:
從3.9 -> 3.12 ,換完之后 ,成功
驗證 安裝成功
pip show pdfplumber
linux下 一樣,pdfplumber 好像需要python3.12 版本:
V2 :
代碼如下:
import streamlit as st
import pdfplumber
import io# 設置頁面標題
st.title("PDF 文本提取工具")# 創建文件上傳組件
uploaded_file = st.file_uploader("請選擇一個 PDF 文件", type=["pdf"])if uploaded_file is not None:# 讀取上傳的文件file_bytes = uploaded_file.read()# 轉換為類文件對象file_stream = io.BytesIO(file_bytes)# 使用 pdfplumber 打開 PDF 文件with pdfplumber.open(file_stream) as pdf:# 獲取第一頁page = pdf.pages[0]# 提取文本text = page.extract_text()# 顯示提取的文本if text:st.subheader("提取的文本內容:")st.write(text)else:st.warning("未能從該頁提取到任何文本。")
else:st.info("請上傳一個 PDF 文件以開始提取文本。")
提取的文本內容:
文旅投集團專屬會員權益服務內容 類型 名稱 項目 具體商品/服務 收費標準 權益折扣 工作日(6:00-17:00) 150元/小時 工作日(17:00-22:00) 200元/小時 周末及節假日(6:00-17:00) 200元/小時 網球項目 8.5折 室內網球 周末及節假日(17:00-22:00) 240元/小時 工作日(6:00-9:00)晨間暢打 399元/10次 工作日(12:00-14:00)午間暢打 299元/10次 工作日(6:00-17:00) 80元/小時 網球項目 工作日(17:00-22:00) 100元/小時 8.5折 室外網球 周末及節假日(6:00-22:00) 100元/小時 工作日(6:00-12:00) 40元/小時 工作日(12:00-17:00) 60元/小時 工作日(17:00-22:00) 80元/小時 多功能館 8.5折 羽毛球 文 周末及節假日(6:00-22:00) 80元/小時 中央綠色 體 體育公園 類 工作日(6:00-9:00)晨間暢打 15元/人 工作日(6:00-9:00)晨間暢打次卡 288元/30次 多功能館 全時段(6:00-22:00) 半場200元/小時 8.5折 室內籃球 工作日(6:00-12:00) 20元/小時 工作日(12:00-22:00) 25元/小時 周末及節假日(6:00-12:00) 25元/小時 乒乓球館 周末及節假日(12:00-22:00) 30元/小時 8.5折 乒乓球 工作日(6:00-9:00)暢打次卡 120元/30次 工作日(9:00-12:00)暢打次卡 150元/30次 工作日(19:00-22:00)暢打次卡 198元/30次 工作日(6:00-17:00) 300元/小時 室外場地 工作日(17:00-22:00) 400元/小時 8.5折 11人制足球 周末及節假日(6:00-22:00) 400元/小時
1-3. v3 使用tk 庫,彈框選擇文件
以下是運行完整示例程序并進行測試的詳細步驟說明:
運行環境準備
- 安裝依賴庫:
pip install pdfplumber tk
-
pdfplumber:用于PDF解析
-
tk:用于圖形界面(Python自帶,但部分Linux系統可能需要單獨安裝)
-
準備測試文件:
-
準備一個測試用的PDF文件(建議同時準備正常PDF和錯誤文件用于測試異常處理)
完整代碼保存
新建一個.py文件(如pdf_extractor.py),粘貼以下代碼:
import pdfplumber
import io
import tkinter as tk
from tkinter import filedialog# 創建隱藏的根窗口
root = tk.Tk()
root.withdraw()# 打開文件選擇對話框
file_path = filedialog.askopenfilename(title="選擇PDF文件",filetypes=[("PDF文件", "*.pdf")]
)if not file_path:print("未選擇文件")exit()try:# 先讀取為字節數據with open(file_path, "rb") as f:file_bytes = f.read()# 轉換為類文件對象file_stream = io.BytesIO(file_bytes)# 解析PDFwith pdfplumber.open(file_stream) as pdf:first_page = pdf.pages[0]print("="*30 + "\n提取的文本內容:\n" + "="*30)print(first_page.extract_text() or "未檢測到文本內容")except Exception as e:print(f"處理文件時出錯:{str(e)}")
運行測試步驟
####. 方式一:圖形界面方式(推薦)
啟動程序:
python pdf_extractor.py
- 選擇文件:
- 將自動彈出文件選擇對話框
- 選擇準備好的測試PDF文件(建議選擇包含可識別文本的簡單PDF)
- 查看輸出:
==============================
提取的文本內容:
==============================
這里是PDF第一頁的文本內容...
方式二:命令行方式(適用于自動化)
python pdf_extractor.py "/path/to/your/file.pdf"
測試用例示例
測試場景 | 預期結果 | 驗證點 |
---|---|---|
-------- | -------- | ----- |
選擇正常PDF文件 | 正確輸出第一頁文本 | 文本提取功能正常 |
取消文件選擇 | 輸出"未選擇文件"并退出 | 異常處理邏輯正常 |
選擇非PDF文件(如.jpg) | 彈出錯誤提示 | 文件類型過濾有效 |
選擇加密的PDF文件 | 拋出解密錯誤 | 異常處理機制有效 |
選擇損壞的PDF文件 | 顯示解析錯誤信息 | 健壯性驗證 |
常見問題排查
1. 無文件選擇對話框彈出:
- 檢查是否安裝了圖形界面支持
- 在Linux服務器環境可使用以下命令安裝基礎GUI支持:
sudo apt-get install python3-tk
2. No such file or directory錯誤:
- 確認文件路徑是否正確
- 檢查文件權限設置
3. 提取內容為空:
- 測試文件是否是掃描版圖片PDF(需要OCR處理)
- 嘗試使用官方測試文件:
# 測試代碼
import pdfplumber
with pdfplumber.open("https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf") as pdf:print(pdf.pages[0].extract_text())
4. 內存不足錯誤:
對于超大PDF文件(>100MB),改用文件路徑方式打開:
# 替代BytesIO的方式
with pdfplumber.open(file_path) as pdf:# 處理邏輯
擴展測試建議
- 多頁測試:
# 修改代碼遍歷所有頁面
for i, page in enumerate(pdf.pages):print(f"第 {i+1} 頁內容:")print(page.extract_text())
- 表格提取測試: TODO 看看能不能 彌補上面 V2 解析結果錯亂的問題
# 在with語句中添加
table = first_page.extract_table()
if table:print("\n檢測到表格:")for row in table:print(row)
- 性能測試:
import time
start = time.time()
# 處理代碼
print(f"處理耗時:{time.time()-start:.2f}秒")
通過以上步驟可以完整驗證PDF文本提取功能的可用性和健壯性。
1-10 總結:
這段代碼實現了從一個名為 example.pdf
的 PDF 文件中提取第一頁的文本,并將其輸出到控制臺。它適合用于快速查看或處理 PDF 中的文本信息。
如果你有 PDF 文件想解析或提取特定內容,也可以告訴我,我可以幫你構建更復雜的提取邏輯。
二. PDF中包含表格,table = first_page.extract_table() 只能提取到 PDF文件中的表頭如下:
提取的文本內容:
==============================
['類型', '名稱', '項目', '具體商品/服務', '收費標準', '權益折扣']
表格里的單元格數據 提取不到
1. 表格結構識別問題
pdfplumber 是基于規則來識別表格的,若表格的結構較為復雜或者不規則,它可能無法正確識別表格的邊界,進而導致只能提取到表頭。
解決辦法
調整表格檢測參數:可以通過修改 table_settings 參數來調整表格檢測的規則。例如,修改 vertical_strategy 和 horizontal_strategy 參數,讓其能更精準地識別表格的邊界。
import pdfplumberpdf_path = 'your_pdf_file.pdf'
with pdfplumber.open(pdf_path) as pdf:first_page = pdf.pages[0]# 調整表格檢測參數table_settings = {"vertical_strategy": "text","horizontal_strategy": "text"}table = first_page.extract_table(table_settings)for row in table:print(row)
效果:
有單元格內容,也能成行成行打印了,但是對于前2列 是合并行的單元格,還不友好。
2. 文本布局問題
若表格中的文本布局比較特殊,例如存在合并單元格、跨頁表格等情況,pdfplumber 可能難以正確識別表格的結構。
解決辦法
- 手動指定表格區域:可以通過指定表格的坐標區域來精確提取表格數據。你可以使用 pdfplumber 的 crop() 方法來裁剪頁面,只保留表格所在的區域。
生成 pdf_table_extraction_manual.py。 未測試驗證
import pdfplumberpdf_path = 'your_pdf_file.pdf'
with pdfplumber.open(pdf_path) as pdf:first_page = pdf.pages[0]# 手動指定表格區域的坐標(x0, top, x1, bottom)table_bbox = (100, 200, 500, 400)cropped_page = first_page.crop(table_bbox)table = cropped_page.extract_table()for row in table:print(row)
3. 字體和顏色問題
如果表格中的文本使用了特殊的字體或者顏色,pdfplumber 在識別文本時可能會出現問題。
解決辦法
- 檢查 PDF 文件:嘗試使用 PDF 閱讀器打開文件,查看表格中的文本是否能夠正常顯示。若文本顯示存在問題,可以嘗試重新生成 PDF 文件。