
OCRmyPDF 常见报错详解文本层冲突、无效 PDF 与 Tesseract 配置缺失的成因和解决【免费下载链接】OCRmyPDFOCRmyPDF adds an OCR text layer to scanned PDF files, allowing them to be searched项目地址: https://gitcode.com/GitHub_Trending/oc/OCRmyPDFOCRmyPDF 在处理 PDF 时会做多层校验最常见的三类报错——page already has text、Input file is not a valid PDF 和 Tesseract cannot open its config file——分别对应输入文件的文本层状态、PDF 结构合法性与 Tesseract 运行环境三个独立问题。本文逐一解析每条报错的触发条件、底层检测逻辑与源码位置并给出可复制的解决命令帮助你在批量处理 PDF 时准确定位故障根因并选择正确的处理模式--force-ocr/--skip-text/--redo-ocr/--mode。报错与退出码的对应关系在逐条分析之前先了解 OCRmyPDF 的报错机制所有致命错误都由 src/ocrmypdf/exceptions.py 中的ExitCodeException子类承载每个异常携带一个固定的退出码便于脚本和批处理任务判断失败原因。与本文三节直接相关的退出码定义在 ExitCode异常退出码含义InputFileError2 (input_file)输入文件有问题如无效 PDFPriorOcrFoundError6 (already_done_ocr)文件已含 OCR 文本层TesseractConfigError9 (invalid_config)Tesseract 配置解析/读取失败下面按 docs/errors.md 的章节顺序逐一展开这三条最常见的 ERROR 日志。page already has text! – aborting页面已有文本层报错原文与含义ERROR - 1: 页码: page already has text! – aborting (use --force-ocr to force OCR)这条错误说明你对一个已经包含可打印文本或隐藏 OCR 文本层的文件运行了 OCRmyPDF两者在检测层面几乎无法区分。此时默认行为是中止因为文件本身已经可搜索重复 OCR 通常没有意义。源码中的检测逻辑检测发生在 src/ocrmypdf/_pipeline.py 的is_ocr_required()函数约 L337–L415。核心判断是pageinfo.has_text当某页检出文本且处理模式为default时抛出异常elif pageinfo.has_text: if options.mode ProcessingMode.default: raise PriorOcrFoundError( page already has text! - aborting (use --force-ocr or --mode force to force OCR; see also help for --skip-text, --redo-ocr, and --mode) ) elif options.mode ProcessingMode.force: log.info(page already has text! - rasterizing text and running OCR anyway) ocr_required True elif options.mode ProcessingMode.redo: ... elif options.mode ProcessingMode.skip: log.info(skipping all processing on this page) ocr_required FalsePriorOcrFoundError定义在 src/ocrmypdf/exceptions.py#L75-L78对应退出码 6。这意味着在批量脚本中捕获退出码 6 即可专门识别文件已有文本层这一类情况例如 misc/batch.py 中的批处理示例就显式捕获了ocrmypdf.exceptions.PriorOcrFoundError。三种解决方式以及新的--mode选项报错信息本身给出了三个选项它们在新版中统一由--mode参数表达。ProcessingMode枚举定义在 src/ocrmypdf/_options.py#L37-L55ocrmypdf --force-ocr等价于--mode force把全部矢量内容栅格化成图片再运行 OCR。适用于之前的 OCR 程序失败需要重做、或文档中含有文本水印等需要推倒重来的场景。从源码看force模式下已含文本的页面会被记录为rasterizing text and running OCR anyway并强制继续。ocrmypdf --skip-text等价于--mode skip对含文本的页面跳过 OCR 及其他处理这些页面原样拷贝进输出 PDF。适合扫描页与纯文本页混排的文件。ocrmypdf --redo-ocr等价于--mode redo扫描并移除文件中已有的 OCR不可打印文本层后重新执行 OCR。这是利用新版 Tesseract 精度提升来重做旧 OCR 层的推荐方式。可打印的矢量文本不在清除范围内因此该模式也适用于数字文本与扫描页混合的文件。从 _options.py 的向后兼容属性L161–L175 附近可以确认force_ocr、skip_text、redo_ocr这些历史布尔标志现在都只是--mode force/skip/redo的别名且validate_redo_ocr_options()会校验--redo-ocr与其他互斥选项的组合合法性。另外枚举中还定义了strip模式Remove the invisible OCR text layer in place; do not OCR用于只剥离旧文本层而不重新 OCR。Input file filename is not a valid PDF输入文件无法解析OCRmyPDF 在正式处理前会先用 pikepdf 库打开并修复输入文件pikepdf 底层依赖 libqpdf 来尝试修复 PDF 中的常见错误。当连 libqpdf 都无法解析时就会抛出这条错误。多数情况下原因是PDF 损坏或被截断典型的如文件复制不完整此时能做的修复手段有限。这条检查的源码位置在 src/ocrmypdf/_pipeline.py#L182-L198try: with pikepdf.open(input_file) as pdf: ... pdf.save(output_file) except pikepdf.PdfError as e: raise InputFileError() from e except pikepdf.PasswordError as e: raise EncryptedPdfError() from epikepdf.PdfError被包装为InputFileError退出码为 2input_file而pikepdf.PasswordError则单独报EncryptedPdfError退出码 8。测试资源 tests/resources/invalid.pdf 就是一个用于验证此路径的无效 PDF 样本。修复手段用 Ghostscript 或 pdftk 重写文件如果文件只是轻微损坏可以尝试让 Ghostscript 重新写出一份干净的 PDFgs -o output.pdf -dSAFER -sDEVICEpdfwrite input.pdfpdftk同样具备重写 PDF 的能力pdftk input.pdf cat output output.pdf此外Adobe Acrobat 的 Preflight 工具在部分损坏场景下也能完成修复。若上述重写命令同样失败基本可以确认文件已不可恢复需要找回完整的原始副本。Tesseract cannot open its config file hocr or txttessdata 缺少 configs 目录报错原文与底层原因ERROR - Tesseract cannot open its config file hocr.OCRmyPDF 要求 Tesseract 以hocr和txt两种格式输出识别结果而 Tesseract 对这两种输出格式的规则指令保存在其tessdata目录的configs/子目录中分别命名为hocr和txt两个配置文件。这两个文件缺失时Tesseract 的表现极具迷惑性它打印read_params_file: Cant open hocr、以退出码 0无错误退出、且不产生任何输出。OCRmyPDF 专门处理了这种静默失败。src/ocrmypdf/_exec/tesseract.py 中的tesseract_log_output()函数约 L318–L336逐行解析 Tesseract 的日志elif read_params_file in line.lower(): tlog.error(line.strip()) # Tesseract emits read_params_file: Cant open name when it # cannot locate a config file (e.g. hocr, txt) in its # tessdata configs/ directory, then exits 0 without producing # the requested output. Promote to a hard error so the user # sees the root cause instead of a downstream FileNotFoundError. if Cant open in line: missing line.split(Cant open, 1)[1].strip() ... raise TesseractConfigError( fTesseract cannot open its config file {missing}. ... )注释说明了设计意图把 Tesseract 的退出码 0 提升为硬性错误TesseractConfigError退出码 9让用户直接看到根因而不是下游模棱两可的FileNotFoundError。该检测逻辑有对应的测试覆盖见 tests/test_tesseract.py#L160-L162。典型触发场景这种情况通常发生在手工拼装tessdata目录时例如只从 Tesseract 官方的tessdata_best等训练数据仓库逐个下载.traineddata语言包再把环境变量TESSDATA_PREFIX指向该目录——这类仓库并不包含configs/目录因此hocr/txt配置文件缺失。而通过操作系统包管理器安装的完整 Tesseract如 Debian/Ubuntu 的tesseract-ocr包会自带这些文件。解决方法确保 Tesseract 实际使用的tessdata目录中存在configs/hocr和configs/txt两个文件即可。最简单的做法是从一个完整安装的 Tesseract 中把整个configs/目录复制过来放到你的tessdata目录下。如果你通过TESSDATA_PREFIX指定了非默认路径请务必核对该路径下的configs/子目录是否齐全。小结按退出码定位故障把三节内容串起来处理 OCRmyPDF 失败时的排查路径是退出码 2InputFileError输入文件本身的问题——优先用 Ghostscript 的pdfwrite设备重写文件确认不是复制截断导致退出码 6PriorOcrFoundError文件已有文本层——按目标选择--mode force推倒重来、--mode skip保留文本页或--mode redo移除旧 OCR 层后重做退出码 9TesseractConfigErrorTesseract 环境问题——补齐tessdata/configs/目录中的hocr与txt文件。所有异常的完整清单包括加密 PDF、数字签名、非嵌入 CID 字体等更专业的场景可参阅 src/ocrmypdf/exceptions.py错误信息的统一模板则来自基类ExitCodeException的message属性机制。【免费下载链接】OCRmyPDFOCRmyPDF adds an OCR text layer to scanned PDF files, allowing them to be searched项目地址: https://gitcode.com/GitHub_Trending/oc/OCRmyPDF创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考