提取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()); }
} } ?></pre>
本項目中是通過前端請求來調用上訴類中的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();
}</pre>
<!-- 網頁代碼 --> <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;
} } ?></pre>
同樣通過前端異步請求來調用上訴類中的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();
}</pre>
<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></pre>
測試網址:http://www.cffex.com.cn/tzgg/jysgg/201512/W020151204630497494614.pdf
![]()
優點:不存在亂碼
來自:http://www.cnblogs.com/yinhutaxue/p/Yihoo.html