18:PDF 转 Word------利用 OCR 技术批量提取不可编辑的文档内容
第三阶段:PDF 与图片处理(16-22)
场景引入
收到一份扫描版 PDF 合同,里面的文字无法复制、无法搜索、无法编辑。需要将其转换为可编辑的 Word 文档。手动逐字输入太慢,用免费转换工具又有页数限制。
本节教你用 Python 批量将 PDF 转为 Word,特别是扫描件(图片格式)也能通过 OCR 提取文字。
技术原理
PDF 转 Word 分两种情况:
| PDF 类型 | 特点 | 处理方式 |
|---|---|---|
| 文字型 | 文字可复制选择 | 直接提取文字 |
| 扫描型 | 实质是图片 | 需要 OCR 识别文字 |
OCR(光学字符识别)流程
扫描 PDF → 每页转为图片 → Tesseract OCR 识别文字 → 写入 Word 文档
环境准备
方案 1:文字型 PDF(简单)
bash
pip install pdfplumber python-docx
方案 2:扫描型 PDF(OCR)
bash
pip install pytesseract pdf2image python-docx Pillow
还需要安装 Tesseract OCR 引擎:
- 下载:https://github.com/UB-Mannheim/tesseract/wiki
- 安装后设置环境变量,或在代码中指定路径
完整代码
方案 1:文字型 PDF 转 Word
python
import pdfplumber
from docx import Document
from pathlib import Path
def pdf_to_word_text(input_pdf, output_docx):
"""
将文字型 PDF 转换为 Word 文档
参数:
input_pdf: 源 PDF 文件
output_docx: 输出 Word 文件
"""
doc = Document()
with pdfplumber.open(input_pdf) as pdf:
total_pages = len(pdf.pages)
print(f"共 {total_pages} 页,开始转换...")
for i, page in enumerate(pdf.pages):
# 提取文字
text = page.extract_text()
if text:
doc.add_paragraph(text)
# 添加分页符(除最后一页)
if i < total_pages - 1:
doc.add_page_break()
print(f"已转换第 {i+1} 页")
doc.save(output_docx)
print(f"\n转换完成: {output_docx}")
# 提取表格
def pdf_tables_to_word(input_pdf, output_docx):
"""
将 PDF 中的表格提取到 Word
"""
doc = Document()
with pdfplumber.open(input_pdf) as pdf:
for i, page in enumerate(pdf.pages):
tables = page.extract_tables()
for table_idx, table in enumerate(tables):
if table:
doc.add_heading(f"第 {i+1} 页 - 表格 {table_idx+1}", level=2)
# 创建 Word 表格
word_table = doc.add_table(rows=len(table), cols=len(table[0]))
for row_idx, row in enumerate(table):
for col_idx, cell in enumerate(row):
word_table.cell(row_idx, col_idx).text = str(cell or '')
doc.save(output_docx)
print(f"表格提取完成: {output_docx}")
方案 2:扫描型 PDF(OCR)转 Word
python
import pytesseract
from pdf2image import convert_from_path
from docx import Document
import os
# Tesseract 路径(根据实际安装位置修改)
TESSERACT_PATH = r"C:\Program Files\Tesseract-OCR\tesseract.exe"
pytesseract.pytesseract.tesseract_cmd = TESSERACT_PATH
def ocr_pdf_to_word(input_pdf, output_docx, lang='chi_sim+eng'):
"""
使用 OCR 将扫描版 PDF 转为可编辑 Word
参数:
input_pdf: 扫描版 PDF
output_docx: 输出 Word
lang: OCR 语言,'chi_sim'=简体中文,'eng'=英文,可组合
"""
doc = Document()
# PDF 每页转为图片
print("正在将 PDF 转为图片...")
images = convert_from_path(input_pdf, dpi=300)
print(f"共 {len(images)} 页")
for i, image in enumerate(images):
print(f"OCR 识别第 {i+1} 页...")
# OCR 识别
text = pytesseract.image_to_string(image, lang=lang)
# 写入 Word
doc.add_paragraph(text)
if i < len(images) - 1:
doc.add_page_break()
doc.save(output_docx)
print(f"\nOCR 转换完成: {output_docx}")
方案 3:批量转换文件夹中的所有 PDF
python
def batch_pdf_to_word(folder_path, output_dir="Word文档", use_ocr=False):
"""
批量转换文件夹中的所有 PDF
"""
folder = Path(folder_path)
output = Path(output_dir)
output.mkdir(parents=True, exist_ok=True)
for pdf_file in folder.glob('*.pdf'):
word_file = output / f"{pdf_file.stem}.docx"
if use_ocr:
ocr_pdf_to_word(str(pdf_file), str(word_file))
else:
pdf_to_word_text(str(pdf_file), str(word_file))
print(f"\n批量转换完成! 输出目录: {output_dir}/")
常见问题
Q1:OCR 识别率低?
- 提高 DPI :
convert_from_path(input_pdf, dpi=600)--- DPI 越高,识别越准确 - 图像预处理:转换为灰度、二值化后再识别
- 语言包:确保安装了正确的语言包
Q2:中文识别出来是乱码?
确保 Tesseract 安装了中文语言包:
- 下载
chi_sim.traineddata放到Tesseract-OCR\tessdata\目录 - 使用
lang='chi_sim'参数
Q3:转换后格式丢失?
OCR 只能提取文字,无法保留原始格式(字体、图片、表格等)。如需保留格式,建议使用专业工具(如 Adobe Acrobat、WPS 会员版)。
总结
| PDF 类型 | 方案 | 准确率 | 速度 |
|---|---|---|---|
| 文字型 | pdfplumber |
100% | 快 |
| 扫描型 | Tesseract OCR | 85-95% | 中等 |
| 含表格 | pdfplumber.extract_tables() |
高 | 快 |
本节掌握了 PDF 转 Word 的两种方法:文字型直接提取 + 扫描型 OCR 识别。
下一节预告:19:图片水印添加------一键为数千张员工工牌或产品图加盖 Logo!