用手机或者Kindle看PDF文档字实太是太小了,总觉得PDF转TXT是个刚需,却一直没找到PDF转TXT的简单方法,最近有空,不妨自己用Python写一个。
将PDF格式转换成纯文本的TXT,虽然会损失掉一些排版和图片,却可以给文件瘦身,也可将其中的文字用于更多场合。
PDF里一般都包含文字和图片,有些文字以图片形式存储,比如大多数以扫描方式制作的PDF图书都使用这种方式,以此方式存储的PDF文件占空间也比较大,一般都有几十兆。另一种,以文本方式存储字符,同时存储字符的大小和位置,在显示对应的页面时绘制图片和文字,以此方式存储的PDF文件占空间较小,一般只有几兆大小。
分辨文字的存储方式很简单,只需要用任意支持PDF格式的软件打开文件,放大几倍,如果文字依然清晰,则是以字符方式存储的,如果字的边缘变得模糊,则一般是以图片方式存储文字。
以字符方式存储PDF的文本比较容易获取,使用Linux下的pdftotxt命令即可过滤出其中的文字。以图片方式存储的相对比较复杂,需要识别图片中的文字,会用到OCR技术,OCR是光学字符识别的简称,目前的OCR一般利用深度学习技术实现,同样也是训练模型比较困难,但单纯地使用模型则非常简单。
本文使用现成的Python三方库,实现对PDF中文本和图片两种文字的识别,程序运行环境仍然是Linux(主要因为笔者不怎么用Windows),Python版本为3.6(与Python 2.7的三方库略有差异)。
安装软件
程序主要包括解析PDF格式和OCR识别两部分,首先安装三方库:
本例中使用了在线和离线两种OCR,离线版本识别率稍差,在线版本是百度提供的字符识别服务,对中文识别效果更好,它提供一定的免费额度,但是使用量大时需要付费。
离线OCR
使用OCR的目的是识别图片中的文字,Tesseract是一款由HP实验室开发,由Google维护的开源OCR,支持多种文字,下面看看它的用法。
在线OCR
百度、搜狗、有道等智能云平台都提供在线OCR服务,使用方法也大同小异,下面介绍百度OCR的使用方法。
其中的appId, apiKey, secretKey需要在百度智能云中创建自己的“文字识别”项目后获取,请访问:https://console.bce.baidu.com/。
识别效果如下图所示,其中左侧是被识别的原始图像,右侧上方是tesseract识别的效果图,右侧下方是百度OCR识别的效果图。百度OCR比tesseract识别效果稍好,尤其是对中英文混排、标点符号和数字效果更好,不过tesseract也基本可用。
PDF格式解析
本例中使用pdfminer库解析PDF文档,完整代码请从github下载:
https://github.com/xieyan0811/pdfconv.git
其中parse_section用于解析数据块,PDF的数据块有LTTextBox,LTFigure,LTImage,LTRect,LTCurve和LTLine等子对象。LTTextBox表示一组文本块可能包含在一个矩形区域; LTTextLine表示单个文本行LTChar对象的列表;LTImage表示一个图像对象;LTLine表示一条直线; LTRect:表示矩形;LTCurve表示曲线。有些对象之间包括嵌套关系。
一些问题
程序通过百余行代码实现转换功能,解析普通的PDF文件问题不大,但仍存在一些问题:
(1) 本文中使用的pdfminer库中对pdf文件中数据块的解析不够完美,只支持主流的jpg、bmp格式文件,有一些pdf中的图片无法被识别。
(2) 竖版文字也被识别成横版。
(3) 解析字符型文本时,比较简单粗暴,对于特殊的版式不一定按照从上到下,从左到右的顺序解析,有待更进。
(4) 程序目前以支持中文PDF文件为主,支持其它语言需要在代码中稍做调整。
参考
(1) 百度接口用法
https://cloud.baidu.com/doc/OCR/OCR-Python-SDK.html#.E9.80.9A.E7.94.A8.E6.96.87.E5.AD.97.E8.AF.86.E5.88.AB