从零开始:安卓手机搭建本地PDF OCR从零开始:安卓手机搭建本地PDF OCR,我踩过的那些坑
写在前面 最近想把手机上的PDF文件转成可编辑的文本,又不想把文件上传到云端,于是决定在安卓上通过 Termux + Python + Tesseract 搭建一套本地OCR方案。 本以为是个常规操作,没想到一路踩坑不断——镜像源被屏蔽、语言包找不到、命令用错、脚本跑不起来……从开始到最终成功,走了不少弯路。 这篇教程不仅记录完整流程,更把每个坑的位置和填坑方法都标出来,希望你能一次性成功,不用重蹈我的覆辙。 一、基础环境搭建(相对顺利的部分) 1.1 安装 Termux ⚠️ 注意:不要从 Google Play 安装 Termux,那个版本已长期未更新,建议从 F-Droid 或 GitHub Releases 下载最新版 。 1.2 安装 Python 和 Tesseract pkg update && pkg upgrade -y pkg install python tesseract poppler -y 为什么安装 poppler? 后面 Python 的 pdf2image 库依赖它来将 PDF 转为图片 。 1.3 安装 Python 依赖库 pip install pytesseract pdf2image Pillow PyPDF2 到这里为止,一切都很顺利,环境搭建好了。然而,真正的挑战才刚刚开始…… 二、语言包安装——噩梦的开始 🕳️ 坑 1:pkg install tesseract-lang-chi_sim 找不到包 安装好 Tesseract 后,想添加中文支持,我理所当然地执行了: pkg install tesseract-lang-chi_sim -y E: Unable to locate package tesseract-lang-chi_sim 原因分析: Termux 仓库中可能根本没有打包这个语言包,或者包名不是我想象的那样 。 🕳️ 坑 2:换源后依然找不到,甚至被镜像站拒绝访问 Sorry, you've been denied access to this page (403) Access denied Error code 403 连续被两个国内主流镜像站拒绝,这才意识到——不是源的问题,是 Termux 仓库本身可能就没有收录 Tesseract 的中文语言包。 搜索 pkg search tesseract 只返回了主包 tesseract 5.5.3,没有任何语言包的信息。 🕳️ 坑 3:尝试 tesseract-data-chi_sim 也不行 不死心,又尝试搜索 tesseract-data 相关包,结果中科大源再次返回 403。 安装 tesseract-data-chi_sim 依然提示: E: Unable to locate package tesseract-data-chi_sim ✅ 最终解决方案:手动下载语言包文件 既然包管理器走不通,那就直接下载 traineddata 文件放到指定目录。 进入 Tesseract 数据目录 cd $PREFIX/share/tessdata 下载简体中文语言包(约 4.6 MB) wget https://github.com/tesseract-ocr/tessdata_fast/raw/main/chi_sim.traineddata 下载英文语言包(通常已自带,如果没有则下载) wget https://github.com/tesseract-ocr/tessdata_fast/raw/main/eng.traineddata 修改文件权限(很重要!) 为什么用 tessdata_fast? 这是速度和精度平衡的版本,适合大多数场景 。如果需要更高精度,可以改用 tessdata_best 版本。 🕳️ 坑 4:chi_sim_vert 竖排模型缺失 echo "你好世界 Hello World" | tesseract stdin stdout -l chi_sim+eng Error opening data file .../chi_sim_vert.traineddata Failed loading language 'chi_sim_vert' 又是一脸懵——明明装了 chi_sim,为什么还要求 chi_sim_vert? 原因: 当使用 chi_sim+eng 组合语言时,Tesseract 会尝试加载相关辅助模型,其中就包括竖排中文模型 chi_sim_vert。如果缺失就会报错,并导致后续参数解析异常。 解决方案: 再下载一个 chi_sim_vert.traineddata 就行了: wget https://github.com/tesseract-ocr/tessdata_fast/raw/main/chi_sim_vert.traineddata chmod 644 $PREFIX/share/tessdata/chi_sim_vert.traineddata 三、测试 OCR——又一个意想不到的坑 🕳️ 坑 5:stdin 不是让你直接传文本的 echo "你好世界 Hello World" | tesseract stdin stdout -l chi_sim+eng Error in fopenReadStream: failed to open locally with tail 你好世界 Hello World for filename 你好世界 Hello World Leptonica Error in pixRead: image file not found: 你好世界 Hello World 这是我犯的一个低级错误。 tesseract stdin 的 stdin 期望接收的是图片数据(PNG、JPEG 等),而不是纯文本字符串。我把文本通过管道传进去,Tesseract 试图把它当作图片文件来解析,当然会报错。 方式一:直接指定图片文件 tesseract /path/to/test.png stdout -l chi_sim+eng 方式二:通过管道传递图片数据(依然需要图片文件) cat /path/to/test.png | tesseract stdin stdout -l chi_sim+eng 如果没有现成的测试图片,可以用 ImageMagick 生成一张: pkg install imagemagick -y convert -size 400x100 xc:white -font Courier -pointsize 24 -fill black -annotate +10+30 "你好世界 Hello World" test.png tesseract test.png stdout -l chi_sim+eng 四、编写 Python 脚本:PDF → TXT 环境没问题了,接下来写 Python 脚本批量处理 PDF。 对每个 PDF,先用 PyPDF2 尝试直接提取文本(适用于文本型 PDF) 如果提取结果为空(说明是扫描件/图片型 PDF),自动回退到 Tesseract OCR 识别 🕳️ 坑 6:运行脚本提示"未找到 PDF 文件" python /sdcard/0/pdf/pdf.py 原因: 我在 ~ 目录下执行脚本,脚本中的 '.' 指向的是当前工作目录(~),而不是脚本所在的目录(/sdcard/0/pdf/),当然找不到 PDF 文件。 方案 操作 说明 ① 先切换目录 cd /sdcard/0/pdf/ && python pdf.py 每次都要 cd ② 指定目录参数 python pdf.py /sdcard/0/pdf/ 灵活但要多输参数 ③ 自动使用脚本目录 修改脚本,用 Path(__file__).parent 一劳永逸 默认使用脚本所在目录 target_dir = str(Path(__file__).parent) 这样无论在哪里执行 python /path/to/pdf.py,都会自动在脚本所在目录下查找 PDF 文件 。 五、完整脚本 - - coding: utf-8 - - from PyPDF2 import PdfReader from pdf2image import convert_from_path ★ 如果 pytesseract 找不到 tesseract,取消下面注释并设置路径 pytesseract.pytesseract.tesseract_cmd = '/data/data/com.termux/files/usr/bin/tesseract' def extract_text_from_pdf_pypdf2(pdf_path): """使用 PyPDF2 提取文本(适用于文本型 PDF)""" reader = PdfReader(pdf_path) for page in reader.pages: page_text = page.extract_text() print(f" [PyPDF2] 提取失败: {e}") def extract_text_from_pdf_ocr(pdf_path): """使用 Tesseract OCR 识别图片型 PDF""" print(f" [OCR] 正在转换 PDF 为图片...") images = convert_from_path(pdf_path, dpi=300) for i, img in enumerate(images, start=1): print(f" [OCR] 正在识别第 {i} 页...") page_text = pytesseract.image_to_string(img, lang=OCR_LANG) print(f" [OCR] 识别失败: {e}") def convert_pdf_to_txt(pdf_path, txt_path): text = extract_text_from_pdf_pypdf2(pdf_path) print(" [提示] 文本提取为空,尝试 OCR 识别...") text = extract_text_from_pdf_ocr(pdf_path) with open(txt_path, 'w', encoding='utf-8') as f: print(f" ✓ 成功保存: {txt_path}") print(f" ✗ 无法提取任何文本: {pdf_path}") 默认使用脚本所在目录,也可以通过命令行参数指定 target_dir = str(Path(__file__).parent) if not os.path.isdir(target_dir): print(f"错误: 目录 '{target_dir}' 不存在") pdf_files = [f for f in os.listdir(target_dir) if f.lower().endswith('.pdf')] print(f"在 '{target_dir}' 中未找到 PDF 文件") print(f"找到 {len(pdf_files)} 个 PDF 文件,开始处理...\n") for pdf_file in pdf_files: pdf_path = os.path.join(target_dir, pdf_file) txt_file = os.path.splitext(pdf_file)[0] + '.txt' txt_path = os.path.join(target_dir, txt_file) convert_pdf_to_txt(pdf_path, txt_path) if __name__ == '__main__': 六、使用说明 pip install PyPDF2 pdf2image pytesseract Pillow cd $PREFIX/share/tessdata wget https://github.com/tesseract-ocr/tessdata_fast/raw/main/chi_sim.traineddata wget https://github.com/tesseract-ocr/tessdata_fast/raw/main/chi_sim_vert.traineddata export TESSDATA_PREFIX=$PREFIX/share/tessdata echo 'export TESSDATA_PREFIX=$PREFIX/share/tessdata' >> ~/.bashrc 将脚本放到 PDF 所在目录,直接执行 或指定目录 python pdf_to_txt.py /sdcard/Download/ 七、踩坑总结 序号 坑 原因 教训 1 pkg install 找不到语言包 Termux 仓库可能未收录语言包 不要依赖包管理器,学会手动下载 2 镜像源 403 被拒 防盗链或异常流量触发 多备几个源,关键时候手动下载更可靠 3 chi_sim_vert 缺失 组合语言会加载辅助模型 不仅下载 chi_sim,还要下载 chi_sim_vert 4 stdin 传文本报错 误解了 stdin 的用途 它接收的是图片数据,不是文本 5 脚本找不到 PDF 文件 工作目录与脚本目录不一致 使用 Path(__file__).parent 自动定位 写在最后 整个折腾过程耗时大半天,但最终跑通的那一刻还是很有成就感的。现在,我的安卓手机已经变身为一台完全离线、保护隐私的 PDF OCR 工作站。 如果你也想在手机上搞一套,希望这篇教程能帮你避开我踩过的那些坑。如果你能一次成功,那这篇文章就没白写 😄 附:实用资源链接 Tesseract 语言包下载(tessdata_fast):https://github.com/tesseract-ocr/tessdata_fast Tesseract 官方文档:https://tesseract-ocr.github.io/ Termux 官方指南:https://termux.dev/