提取pdf文件文本:pdfparser与xpdf具体操作
网上搜索有许多pdf文本提取相关的开发包,仅php语言就有许多。下面是本猿在实践中接触的三种库:
1. PDFLIB TET http://www.pdflib.com/en/download/tet/
2. PDF Parser http://www.pdfparser.org/
3. XPDF http://www.foolabs.com/xpdf/
第一感觉比较满意的是 PDFLIB TET,因为其具有图片提取等功能,然而这个库是收费的,只能看着多达200多页的英文文档无动于衷!作为爱学习的类猿,还是期待大神的出现!
本文主要通过 PDF Parser 和 XPDF 来实现pdf文件中文本的提取工作。
实验环境:
阿里云平台 + ubuntu12.04 + apache2 + php5.3.10 + mysql5.6 (本项目中,整体采用 thinkphp 框架,该功能只是项目的一部分)
PDF Parser
准备工作:
上诉官网下载项目源码:pdfparser-master.zip;
解压源码文件,复制src文件夹下Smalot文件夹(该文件夹中源码是项目的核心源码)到ThinkPHP/Library文件夹下(该文件夹为thinkphp框架中存放第三方库);
修改源代码的命名,如page.php修改为page.class.php(后者为php官方推荐类命名方式);
实验环节:
编写一个类调用上面的库,具体代码
<?php namespace Admin\Controller; use Think\Controller; class PdfParseController extends Controller { //定义方法,解析pdf文件 function parse(){ // 获取参数,文件所在路径 $path = $_GET['path']; // 创建源码中的Parser类对象 $parser = new \Smalot\PdfParser\Parser(); // 调用解析方法,参数为pdf文件路径,返回结果为Document类对象 $document = $parser->parseFile($path); // 获取所有的页 $pages = $document->getPages(); // 逐页提取文本 foreach($pages as $page){ echo($page->getText()); } } } ?>
本项目中是通过前端请求来调用上诉类中的parse()方法,由于存在网络延迟等问题,为了不影响UI体验,采用ajax异步调用
// js文件,页面按钮点击后调用parse方法 var xmlHttp = null; function parse(){ //alert("开始"); var path = document.getElementById("pdffile").value; // 获取文件路径 var url = "http://***.***.***.***/***/***/PdfParse/parse?path=" + path; //请求路径 request(url, function(result){ //回调函数 //alert(result); document.getElementsByName("context")[0].value = result; }); } function request(url, onsuccess){ //获取XMLHttpRequest对象,执行异步请求操作 if (window.XMLHttpRequest) { xmlHttp = new XMLHttpRequest(); } else if (window.ActiveXObject) { xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); } else { alert("Browser does not support HTTP Request"); } xmlHttp.onreadystatechange = function(){ if (xmlHttp.readyState == 4) { if (xmlHttp.status == 200) { // 请求成功返回 onsuccess(xmlHttp.responseText); } } } xmlHttp.open("GET", url, true); xmlHttp.send(); }
<!-- 网页代码 --> <body> <tr> <td>文档解析:</td> <td> <select id="pathtype" name="pathtype" style="width:60px;"> <option value="url">网址</option> </select> <input type="text" id="pdffile" name="pdffile" style="width:500px"> </td> <td colspan="10" > <input type="button" class="input_button" name="parse" value="解析" onclick="parse()" /> </td> </tr> </body>
测试网址:http://www.cffex.com.cn/tzgg/jysgg/201512/W020151204630497494614.pdf
优点:可以直接解析网页中的pdf文件,无需下载;
缺点:部分解析结果存在乱码格式;不支持图片提取
XPDF
准备工作:
上诉官网下载项目:xpdfbin-linux-3.04.tar.gz, xpdf-chinese-simplified.tar.gz;
安装xpdf-3.04到指定目录(本次为/usr/local)
tar zxvf xpdfbin-linux-3.04.tar.gz -C /usr/local //解压到安装目录
cd /usr/local/xpdfbin-linux-3.04 //打开解压文件夹
cat INSTALL
cd bin32/
cp ./* /usr/local/bin/
cd ../doc/
mkdir -p /usr/local/man/man1
mkdir -p /usr/local/man/man5
cp *.1 /usr/local/man/man1
cp *.5 /usr/local/man/man5
至此解析工具已经安装好,可以shell端命令调用解析英文文档,如果需要支持其他语言,需要安装字体插件。下面为简体中文插件安装过程
cp sample-xpdfrc /usr/local/etc/xpdfrc
tar zxvf xpdf-chinese-simplified.tar.gz -C /usr/local
cd /usr/local/xpdf-chinese-simplified
mkdir -p /usr/local/share/xpdf/chinese-simplified
cp -r Adobe-GB1.cidToUnicode ISO-2022-CN.unicodeMap EUC-CN.unicodeMap GBK.unicodeMap CMap /usr/local/share/xpdf/chinese-simplified/
把解压后文件夹chinese-simplified里面文件 add-to-xpdfrc 的内容复制到/usr/local/etc/xpdfrc文件中。
shell端命令调用(W020151204630497494614.pdf文件已经下载到shell命令当前目录中):
pdftotext W020151204630497494614.pdf //没有采用字体库,存在乱码
pdftotext -layout -enc GBK W020151204630497494614.pdf //无乱码
实验环节:
编写一个类调用上面的命令,具体代码
<?php namespace Admin\Controller; use Think\Controller; class PdfParseController extends Controller { function pdftotxt(){ // 获取参数,文件所在路径 $path = $_GET['path']; // 下载文件 $file_name = $this->download($path); // 解析文件 $content = shell_exec('/usr/local/bin/pdftotext -layout -enc GBK '.$file_name.' -'); // 转换文本编码格式 $content = mb_convert_encoding($content, 'UTF-8','GBK'); // 删除下载的文件 unlink($file_name); echo($content); } // 定义函数,下载文件 function download($file_url){ // 判断参数是否赋值及是否为空 if(!isset($file_url)||trim($file_url)==''){ return '500'; } // 返回路径中的文件名部分,包含扩展名 $file_name=basename($file_url); $content = file_get_contents($file_url); file_put_contents($file_name, $content); return $file_name; } } ?>
同样通过前端异步请求来调用上诉类中的parse()方法
var xmlHttp = null; function pdftotxt(){ var path = document.getElementById("pdffile").value; // 获取文件路径 var url = "http://***.***.***.***/***/***/PdfParse/pdftotxt?path=" + path; //请求路径 request(url, function(result){ //回调函数 //alert(result); document.getElementsByName("context")[0].value = result; }); } function request(url, onsuccess){ //获取XMLHttpRequest对象,执行异步请求操作 if (window.XMLHttpRequest) { xmlHttp = new XMLHttpRequest(); } else if (window.ActiveXObject) { xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); } else { alert("Browser does not support HTTP Request"); } xmlHttp.onreadystatechange = function(){ if (xmlHttp.readyState == 4) { if (xmlHttp.status == 200) { // 请求成功返回 onsuccess(xmlHttp.responseText); } } } xmlHttp.open("GET", url, true); xmlHttp.send(); }
<body> <tr> <td>文档解析:</td> <td> <select id="pathtype" name="pathtype" style="width:60px;"> <option value="url">网址</option> </select> <input type="text" id="pdffile" name="pdffile" style="width:500px"> </td> <td colspan="10" > <input type="button" class="input_button" name="parse" value="解析" onclick="parse()" /> </td> <td colspan="10" > <input type="button" class="input_button" name="exchange" value="转换" onclick="pdftotxt()" /> </td> </tr> </body>
测试网址:http://www.cffex.com.cn/tzgg/jysgg/201512/W020151204630497494614.pdf
优点:不存在乱码
来自:http://www.cnblogs.com/yinhutaxue/p/Yihoo.html