Python扫描PDF文字OCR识别 图片转文字教程
用Python把扫描版PDF逐页转图片,再调用OCR引擎识别成文字,支持中文,处理图片型PDF不再手动录入。
场景痛点
扫描件、传真件、盖章合同都是图片型PDF,用pdfplumber/PyPDF2读出来是空字符串。想把里面的文字电子化,要么手打几百页,要么用付费OCR软件。用Python+pdf2image+pytesseract,可以把每页PDF先渲染成图片,再调用本地OCR引擎识别成文字,离线可用、免费、可批量。
用到的库
pip install pdf2image pytesseract
# 系统层依赖:
# 1) 安装 poppler(pdf2image 依赖它把PDF转图片)
# 2) 安装 Tesseract OCR,并下载中文语言包 chi_sim
完整代码
# -*- coding: utf-8 -*-
"""
对扫描版 PDF 做 OCR,把每页识别为文字
"""
from pdf2image import convert_from_path
import pytesseract
# 如果 tesseract 不在 PATH 里,手动指定可执行文件路径
# pytesseract.pytesseract.tesseract_cmd = r"C:\Program Files\Tesseract-OCR\tesseract.exe"
def ocr_pdf(pdf_path: str, out_txt: str = None, lang: str = "chi_sim+eng") -> str:
"""
对整本扫描 PDF 做 OCR
:param pdf_path: 扫描版 PDF 路径
:param out_txt: 可选,识别结果保存路径
:param lang: OCR 语言,中文简体+英文;纯英文改 "eng"
"""
# dpi=300 是扫描件常用精度,太低识别率下降,太高变慢
images = convert_from_path(pdf_path, dpi=300)
print(f"共 {len(images)} 页")
all_text = []
for i, img in enumerate(images, start=1):
# 对这张图片做 OCR,lang 指定语言包
text = pytesseract.image_to_string(img, lang=lang)
all_text.append(f"========== 第 {i} 页 ==========\n{text}")
print(f"第 {i} 页识别完成,{len(text)} 字")
full_text = "\n\n".join(all_text)
if out_txt:
with open(out_txt, "w", encoding="utf-8") as f:
f.write(full_text)
print(f"已保存: {out_txt}")
return full_text
if __name__ == "__main__":
ocr_pdf("扫描件.pdf", "扫描件_识别.txt")
代码讲解
convert_from_path(pdf_path, dpi=300)把PDF每页渲染成 Pillow 图片对象列表,底层调用 poppler。pytesseract.image_to_string(img, lang="chi_sim+eng")调用本地 Tesseract 识别这张图,返回字符串。lang="chi_sim+eng"同时加载简体中文和英文语言包,混合排版识别更准。- 逐页累加文本,最后一次性写 UTF-8 文本文件。
- dpi 是关键参数:150 够清晰,300 更准但慢,600 没必要。
运行结果
控制台逐页打印进度,同目录生成 扫描件_识别.txt。打开后每页文字按页码分隔,可直接做检索、校对。识别率受扫描清晰度、倾斜角度影响。
注意事项
- 系统依赖:pdf2image 需要装 poppler(Windows 下把
bin目录加到 PATH,或用poppler_path=参数指定);Tesseract 要单独安装并下载chi_sim.traineddata中文包。 - 这是离线开源方案,识别率比商业API(百度/腾讯/阿里)低,但胜在免费、可批量、不出本机。
- 倾斜、噪点、手写体会让识别率骤降,必要时先做图像预处理(灰度、二值化、去噪)。
- 识别几十页以上建议加进度条(tqdm)或分批处理,避免误以为卡死。

更新时间:2026-09-14 21:35:46