
OCRmyPDF批处理脚本用Python把整个PDF目录一次跑完别再手动一个个翻【免费下载链接】OCRmyPDFOCRmyPDF adds an OCR text layer to scanned PDF files, allowing them to be searched项目地址: https://gitcode.com/GitHub_Trending/oc/OCRmyPDF手上有几百份扫描版PDF想复制一段文字却发现CtrlC没反应——这些图片型PDF缺的是一层可搜索的文字。OCRmyPDF专门解决这事给扫描PDF加一层文字层让扫描件变得可搜索、可复制。当文件多到不想一个个拖进工具时项目自带的misc/batch.py批处理脚本能递归扫描整个目录自动跑完。读完本文你能用这个脚本批量处理一整个PDF目录并看懂它在背后做了哪些判断。它是什么OCRmyPDF 是一款命令行Python库两用的OCR工具核心机制是渲染-识别-回贴三步先把PDF页面渲染成图片交给 Tesseract 引擎识别出文字及其位置再把文字层以透明方式贴回原PDF最终产物既保留原图像素又能被搜索命中。它不重绘页面只做叠加所以输出文件体积可控、视觉上和原件一致。misc/batch.py则是在这个库之上写的一层薄壳负责找到所有文件 → 判断要不要处理 → 逐个调用 → 记录结果是理解官方推荐用法的最小样板。快速上手装好工具链后依赖 tesseract、ghostscript 等见docs/installation.md最短路径就四步git clone https://gitcode.com/GitHub_Trending/oc/OCRmyPDF cd OCRmyPDF pip install . python3 misc/batch.py /path/to/your/pdfs第一个命令行参数是待处理的目录第二个可选参数是日志文件路径缺省写到脚本旁的ocr-tree.log。跑完后打开日志你会看到每个文件的处理结论。目录换掉这一处其余不用动。关键能力拆解跑通之后我们拆开看这个脚本到底在做什么。它本身不长但每一段都在替你做工程决策。递归扫描整个目录的PDF发现机制这一能力解决的是文件散落在多层子目录的问题。脚本用一行Path.glob把所有PDF一网打尽start_dir Path(sys.argv[1]) if len(sys.argv) 1 else Path() for filename in start_dir.glob(**/*.pdf): logging.info(fProcessing {filename})**/*.pdf里的**表示不限层级递归。设计上把起点做成命令行参数而非写死路径是因为批处理脚本天然要服务于不同归档结构写死反而每次都要改代码。你只需要保证传入的目录存在。自动跳过已有文字、加密与签名文件的判断逻辑不是每个PDF都值得跑OCR——已经带文字层、被加密、带数字签名的文件要么无需处理要么碰了会出事。脚本用先问一次、再试一次、失败分诊的方式处理if ocrmypdf.pdfa.file_claims_pdfa(filename)[pass]: logging.info(Skipped document because it already contained text)先做廉价的格式探测进入ocr()后再靠异常类型把加密 / 已有OCR / 有签名 / 已是tagged分别拦截并写日志。这样设计的意图是批处理跑的是大批量文件个别文件报错绝不能让整批中断所以每一类跳过都单独捕获、单独留痕跑完翻日志就知道哪些文件被跳过、为什么。多页并发与进度输出的流水线执行真正干活的是ocr()内部那条渲染→识别→回贴流水线。对多页PDF它会按页数开并发默认用满CPU核边识别边刷进度条像上图那样每页都有百分比和耗时。这一层是库封装好的批处理脚本不用管并发细节直接继承收益代价是它占用内存和CPU较多这也是后面踩坑里要控的地方。原始文件备份与日志留痕脚本在改文件前可选地把原件拷进备份目录再就地覆写archive_filename archive_dir str(filename) if len(archive_dir) 0 and not filecompare(filename, archive_filename): shutil.copy2(filename, posixpath.dirname(archive_filename))先留底、再就地改是为了让OCR结果可回滚——识别错了至少原件还在。filecompare这一步避免重复拷贝已备份过的文件。日志侧用logging追加模式写入时间戳结论一行一条方便事后再定位某个文件的结果。配置与定制真正可调的入口不多都是什么时候改很明确的那种archive_dir→ 控制原件备份到哪 → 需要给扫描件留底、要求可回滚时改成实际目录不需要就设为空字符串第二个命令行参数日志路径→ 控制日志写到哪里 → 想统一归档日志时改它deskew→ 是否自动纠偏倾斜页面 → 扫描件普遍歪斜时保留Truejobs传给ocr()→ 控制并发页数 → 机器核少或内存紧张时调小避免OOMoptimize传给ocr()→ 控制0~5的输出压缩级别 → 产物太大想瘦身时调高language传给ocr()→ 控制识别语言默认eng→ 处理非英文文档时必须改识别率直接取决于它源码关键路径整段逻辑其实就集中在misc/batch.py的主循环里核心是探测分诊for filename in start_dir.glob(**/*.pdf): if ocrmypdf.pdfa.file_claims_pdfa(filename)[pass]: continue try: result ocrmypdf.ocr(filename, filename, deskewTrue) logging.info(result) except ocrmypdf.exceptions.EncryptedPdfError: logging.info(Skipped document because it is encrypted) except ocrmypdf.exceptions.PriorOcrFoundError: logging.info(Skipped document because it already contained text) except ocrmypdf.exceptions.DigitalSignatureError: logging.info(Skipped document because it has a digital signature)前半段是能不能跑的廉价判断后半段是跑了之后出错怎么收场的分诊表。注意ocr(filename, filename)是输入输出同路径即就地覆写配合前面的备份才有安全感。这段代码在src/ocrmypdf/api.py的ocr()与src/ocrmypdf/exceptions.py的异常类共同支撑下运行你改脚本时基本只动这里的except分支和参数。典型落地场景档案室里堆了上千页发票扫描件行政用这个脚本把整个目录扫一遍事后可直接按金额、日期关键词检索翻纸质档案的时间省掉了大半。研究者手头一批论文扫描件引用无法复制跑完批处理后能逐段复制引文、批量做笔记不用再对着图片手动重打。小团队每周收到一批客户扫描合同把脚本接进定时任务自动过一遍第二天打开的就是可全文搜索的PDF人工逐份拖进工具的动作被彻底去掉。踩坑记录与排障现象处理大文件时进程被系统直接杀掉日志停在某页。原因ocr()默认并发占满CPU且每页都渲染成高分辨率图内存峰值高。解法把jobs调小或配合max_image_mpixels限制单页像素上限分批处理大文件。现象整批英文库识别出来的中文全是乱码。原因默认language是eng语言不对识别率断崖式下降。解法给ocr()传languagechi_sim多语言用chi_simeng并确认 tesseract 装了对应训练包。现象某文件被跳过日志写着 encrypted。原因源PDF带打开密码OCRmyPDF 拒绝处理加密文档。解法先解密再去跑脚本本身按设计跳过加密件不要硬塞密码进去。现象想重跑却发现已含文字被跳过。原因PriorOcrFoundError会拦截已有文字层的文件防止重复叠加。解法确需重识别时给ocr()加redo_ocrTrue让脚本重新生成文字层。小结misc/batch.py把OCRmyPDF从单文件工具升维成目录级批处理靠的是递归发现、异常分诊、备份留痕这三件事而识别本身交给库里的并发流水线。你完全可以照它的骨架改成适合自己归档结构的版本——换 glob 规则、增删except分支、调language与jobs就够了。下一步可以顺着src/ocrmypdf/api.py的ocr()参数列表对照docs/apiref.md把optimize、pdf_renderer这几个和产物质量强相关的选项逐个试出来。【免费下载链接】OCRmyPDFOCRmyPDF adds an OCR text layer to scanned PDF files, allowing them to be searched项目地址: https://gitcode.com/GitHub_Trending/oc/OCRmyPDF创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考