开源项目 从主流文档中提取内容的开源工具比较和选择

santochancf · 2015年10月31日 · 4460 次阅读

在 Fiberead,需要将一些常见格式的文档(如 Word,PDF 等)中的文字提取出来,方便进一步分析和处理。刚开始处理的文档很少,就「Quick and Dirty」的使用 OpenOffice 的headless模式来做了转换。随着业务扩展,需要处理的文档越来越多,大量文档的的并行处理会启动很多 OpenOffice 的进程,占用过多的系统资源,从而导致一些提取工作失败。虽然通过重试机制还可以保证处理完成,但这种方案明显已经不稳定了。所以花了一些时间进行改进了一下文本提取任务。这里顺便比较一下常见的开源工具。

OpenOffice/LibreOffice

OpenOffice/LibreOffice(后简称为OpenOffice)是最初的选择方案。主要一个优势是可以处理Doc(Word 97)格式的文档。OpenOffice 使用headless模式可以一个命令完成文件转换,但每次都要启动一下 OpenOffice 进程。通过阅读文档发现,OpenOffice 是可以通过服务端模式启动,监听一个端口来处理转换请求。如:

/Applications/LibreOffice.app/Contents/MacOS/soffice --headless --accept="socket,host=127.0.0.1,port=8100;urp;"

但是接口方式是UNO. 然后原生 Language Binding 里没有 Ruby。这样就无法通过 Ruby 直接调用这个服务。使用 Ruby 实现一个又会花费很多时间。

由于支持 Python,所以旧有 Python 实现的UnoConv。这个工具封装了一下监听,比较方便调用:

unoconv --listener
unoconv -f txt test.doc

这样可以通过启动这个服务,通过调用unoconv命令完成转换。 基于 OpenOffice 的处理办法都有一个通用的问题,就是输出无法支持 STDOUT,使用 Ruby 做 Wrapper 时就还需要创建读取临时文件来处理。

Tika

Apache Tika (后简称 Tika) 是一个 Java 实现的文档文本提取工具,也支持提取一些文档的的元数据。Tika 可以支持更多的格式,包括并不限于:MS Office 的各种格式,iWorks,CAD,甚至图片和视频的文本也可以提取。Tika 是一个 Java Library, 所以可以通过程序调用。同时也支持命令进行转换,如: java -jar tika.jar -t test.doc

同时还单独提供了 Server 版,可以通过 HTTP 的接口转换文档:

java -jar ./tika-server-1.11.jar
curl -T test.docx http://localhost:9998/tika --header "Accept: text/plain

这种方式对 Ruby 来说更加友好。可以方便使用以下代码完成转换

require 'curb'

c = Curl::Easy.new("http://localhost:9998/tika")
c.headers["Accept"] = "text/plain"
c.http_put(File.open(file_path, econding: 'UTF-8').read)
c.body_str.force_encoding('UTF-8')

简单比较

名称 调用方式 运行内存占用 安装文件大小 性能比较
OpenOffice Ruby -> Python process -> OpenOffice UNO 40MB + 19MB*N(OpenOfficePython 进程) 约 1GB 1000 20KB Doc 文件耗时 4 秒
Apache Tika Ruby -> HTTP PUT Request 100MB 56MB 1000 20KB Doc 文件耗时 160 秒

结论

使用 Apache Tika 可以快速完成升级,并且便于后面扩展。所以可以做一个 Upstart Script,方便将 Tika 运行为服务:

description     "Apache Tika Server"

start on filesystem or runlevel [2345]
stop on shutdown

respawn
respawn limit 3 12

exec java -jar /opt/tika/tika-server-1.11.jar

Gist

暂无回复。
需要 登录 后方可回复, 如果你还没有账号请 注册新账号