Tika常見格式文件抽取內容並做預處理
作者 白寧超
2016年3月30日18:57:08
摘要:本文主要針對自然語言處理(NLP)過程中,重要基礎部分抽取文本內容的預處理。首先我們要意識到預處理的重要性。在大數據的背景下,越來越多的非結構化半結構化文本。如何從海量文本中抽取我們需要的有價值的知識顯得尤為重要。另外文本格式常常不一,諸如:pdf,word,excl,xml,ppt,txt等常見文件類型你或許經過一番周折還是有辦法處理的。倘若遇到database,html,郵件,RTF,圖像,語音等文件,你是否素手無策了。基於此本文總結Apache Tika內容抽取工具,其強大之處在於可以處理各種文件,另外節約您更多的時間用來做重要的事情。本文第一節采用核心概念講解第二節知識擴展補充。第三節典型DOME配有源代碼第四節參考核心文件和Tika工具的JAR包共享。(本文作者原創,匯編整理所得,轉載請注明:Tika常見格式文件抽取內容並做預處理)
目錄
【文本挖掘(1)】OpenNLP:駕馭文本,分詞那些事
【文本挖掘(2)】【NLP】Tika 文本預處理:抽取各種格式文件內容
【文本挖掘(3)】自己動手搭建搜索工具
1 Tika介紹
Tika概念
Tika是一個內容分析工具,自帶全面的parser工具類,能解析基本所有常見格式的文件,得到文件的metadata,content等內容,返回格式化信息。總的來說可以作為一個通用的解析工具。特別對於搜索引擎的數據抓去和處理步驟有重要意義。Tika是Apache的Lucene項目下面的子項目,在lucene的應用中可以使用tika獲取大批量文檔中的內容來建立索引,非常方便,也很容易使用。Apache Tika toolkit可以自動檢測各種文檔(如word,ppt,xml,csv,ppt等)的類型並抽取文檔的元數據和文本內容。Tika集成了現有的文檔解析庫,並提供統一的接口,使針對不同類型的文檔進行解析變得更簡單。Tika針對搜索引擎索引、內容分析、轉化等非常有用。
Tika架構
應用程序員可以很容易地在他們的應用程序集成Tika。Tika提供了一個命令行界面和圖形用戶界面,使它比較人性化。在本章中,我們將討論構成Tika架構的四個重要模塊。下圖顯示了Tika的四個模塊的體系結構:
- 語言檢測機制。
- MIME檢測機制。
- Parser接口。
- Tika Facade 類.
語言檢測機制
每當一個文本文件被傳遞到Tika,它將檢測在其中的語言。它接受沒有語言的注釋文件和通過檢測該語言添加在該文件的元數據信息。支持語言識別,Tika 有一類叫做語言標識符在包org.apache.tika.language及語言識別資料庫里面包含了語言檢測從給定文本的算法。Tika 內部使用N-gram算法語言檢測。
MIME檢測機制
Tika可以根據MIME標准檢測文檔類型。Tika默認MIME類型檢測是使用org.apache.tika.mime.mimeTypes。它使用org.apache.tika.detect.Detector 接口大部分內容類型檢測。內部Tika使用多種技術,如文件匹配替換,內容類型提示,魔術字節,字符編碼,以及其他一些技術。
解析器接口
org.apache.tika.parser 解析器接口是Tika解析文檔的主要接口。該接口從提取文檔中的文本和元數據,並總結了其對外部用戶願意寫解析器插件。采用不同的具體解析器類,具體為各個文檔類型,Tika 支持大量的文件格式。這些格式的具體類不同的文件格式提供支持,無論是通過直接實現邏輯分析器或使用外部解析器庫。
Tika Facade 類
使用的Tika facade類是從Java調用Tika的最簡單和直接的方式,而且也沿用了外觀的設計模式。可以在 Tika API的org.apache.tika包Tika 找到外觀facade類。通過實現基本用例,Tika作為facade的代理。它抽象了的Tika庫的底層復雜性,例如MIME檢測機制,解析器接口和語言檢測機制,並提供給用戶一個簡單的接口來使用。
Tika的特點
-
統一解析器接口:Tika封裝在一個單一的解析器接口的第三方解析器庫。由於這個特征,用戶逸出從選擇合適的解析器庫的負擔,並使用它,根據所遇到的文件類型。
-
低內存占用:Tika因此消耗更少的內存資源也很容易嵌入Java應用程序。也可以用Tika平台像移動那樣PDA資源少,運行該應用程序。
-
快速處理:從應用連結內容檢測和提取可以預期的。
-
靈活元數據:Tika理解所有這些都用來描述文件的元數據模型。
-
解析器集成:Tika可以使用可在單一應用程序中每個文件類型的各種解析器庫。
-
MIME類型檢測: Tika可以檢測並從所有包括在MIME標准的媒體類型中提取內容。
-
語言檢測: Tika包括語言識別功能,因此可以在一個多語種網站基於語言類型的文檔中使用。
Tika的功能
Tika支持多種功能:
- 文檔類型檢測
- 內容提取
- 元數據提取
- 語言檢測
文件類型檢測
Tika使用不同的檢測技術,檢測給它的文件的類型。
內容提取
Tika有一個解析器庫,可以分析各種文檔格式的內容,並提取它們。然后檢測所述文檔的類型,它從解析器庫選擇的適當的分析器,並傳遞該文檔。不同類別的Tika方法來解析不同的文件格式。
元數據提取
隨着內容,Tika提取具有相同的程序的文件的元數據中的內容的提取。對於某些文件類型,Tika有接口類提取元數據。
語言檢測
在內部,Tika如下像一個n-gram算法來檢測所述內容的語言的給定文檔中。Tika取決於類,如語言識別和Profiler的語言識別。
2 核心知識擴展
解析器接口
org.apache.tika.parser.Parser 接口是 Apache Tika 的關鍵組件。它隱藏了不同文件格式和解析庫的復雜性,而同時又為客戶應用程序從各種不同的文檔提取結構化的文本內容以及元數據提供了一個簡單且功能強大的機制。所有這些都是通過一個簡單的方法實現的:
void parse(InputStream stream, ContentHandler handler, Metadata metadata) throws IOException, SAXException, TikaException;
parse
方法接受要被解析的文檔以及相關的元數據作為輸入,並輸出 XHTML SAX 事件以及額外的元數據作為結果。導致這一設計的主要條件如表 1 所示。
表 1. Tika 解析設計的條件
條件 | 解釋 |
---|---|
流線化的解析 |
此接口不應要求客戶應用程序或解析器實現將完整的文檔內容保存在內存內或存放到磁盤。這就讓即便很大的文檔在沒有過多的資源要求的情況下也可被解析。 |
結構化的內容 |
一個解析器實現應該能夠包括所提取內容內的結構信息(標題、鏈接等)。客戶應用程序可以使用這個信息,比如,來更好地判斷這個被解析文檔不同部分的相關性。 |
輸入元數據 |
一個客戶應用程序應該能夠包括像要被解析的文檔的文件名或被聲明的內容類型這類元數據。這個解析器實現可使用這一信息來更好地指導這個解析過程。 |
輸出元數據 |
一個解析器實現應能夠返回除文檔內容外的文檔元數據。很多文檔格式都包含對客戶應用程序非常有用的元數據,比如作者名字。 |
這些條件在 parse
方法的參數內有所體現。
Document InputStream
第一個參數是 InputStream
,用來讀取要被解析的文檔。
如果此文檔流不能被讀取,解析就會停止並且拋出的 IOException
就會被傳遞給客戶應用程序。如果這個流可被讀取但不能被解析(比如文檔被破壞了),解析器就會拋出一個 TikaException
。此解析器實現將會使用這個流,但不會關閉它。關閉流是由最初打開它的這個客戶應用程序負責的。清單 1 顯示了用 parse
方法使用流的建議模式。
清單 1. 用 parse
方法使用流的建議模式
InputStream stream = ...; // open the stream try { parser.parse(stream, ...); // parse the stream } finally { stream.close(); // close the stream }
XHTML SAX 事件
此文檔流的被解析內容被作為 XHTML SAX 事件的一個序列返回給客戶應用程序。XHTML 用來表達此文檔的結構化內容,SAX 事件用來啟用流線化的處理。請注意這里使用了 XHTML 格式,僅僅是為了表達結構化信息,不是為了呈現文檔以供瀏覽。由此解析器實現生成的這些 XHTML SAX 事件被發送至給到 parse
方法的一個 ContentHandler
實例。如果此內容處理程序處理一個事件失敗,解析就會停止並且所拋出的 SAXException
會被發送給客戶應用程序。清單 2 顯示了所生成的這個事件流的整體結構(並且為了清晰,還添加了縮進)。
清單 2. 所生成的這個事件流的整體結構
<html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>...</title> </head> <body> ... </body> </html>
解析器實現通常會使用 XHTMLContentHandler
實用工具類來生成 XHTML 輸出。處理這些原始的 SAX 事件可能會非常復雜,所以 Apache Tika(自 V0.2 開始)攜帶了幾個實用工具類,用來處理事件流並將事件流轉換為其他的表示。
比如,BodyContentHandler
類可用來只提取 XHTML 輸出的主體部分並將其作為 SAX 事件提供給另一個內容處理程序或作為符號提供給一個輸出流、一個編寫器或 一個字符串。如下的代碼片段解析了來自標准輸入流的文檔並將所提取的文檔內容輸出到標准輸出:
ContentHandler handler = new BodyContentHandler(System.out); parser.parse(System.in, handler, ...);
另一個有用的類是 ParsingReader
,它使用了一個后台線程來解析此文檔並作為一個字符流返回所提取的文本內容。
清單 3. ParsingReader
的例子
InputStream stream = ...; // the document to be parsed Reader reader = new ParsingReader(parser, stream, ...); try { ...; // read the document text using the reader } finally { reader.close(); // the document stream is closed automatically }
文檔元數據
parse
方法的最后一個參數用來將文檔元數據傳遞進/出此解析器。文檔元數據被表述為一個元數據對象。表 2 列出了更有趣的一些元數據屬性。
表 2. 元數據屬性
屬性 | 描述 |
---|---|
Metadata.RESOURCE_NAME_KEY |
包含了此文檔的文件或資源名 — 一個客戶應用程序可設置此屬性來讓解析器通過文件名推斷此文檔的格式。如果文件格式包含了規范的文件名(比如,GZIP 格式有一個針對文件名的槽),那么文件解析器實現可設置此屬性。 |
Metadata.CONTENT_TYPE |
此文檔的聲明內容類型 — 一個客戶機應用程序可基於,比如 HTTP Content-Type 頭,設置此屬性。所聲明的內容類型可幫助解析器正確地解析文檔。解析器實現根據被解析的是哪個文檔來將此屬性設置為相應的內容類型。 |
Metadata.TITLE |
文檔的標題 — 如果文檔格式包含了一個顯式的標題字段,那么此屬性將由解析器實現設置。 |
Metadata.AUTHOR |
文檔的作者名 — 如果文檔格式包含了一個顯式的作者字段,那么此屬性將由解析器實現設置。 |
注意到,元數據處理還在 Apache Tika 開發團隊的討論之中,所以在 Tika V1.0 之前的版本,在元數據處理方面有可能會有一些(后向不兼容的)差異。
解析器實現
Apache Tika 自帶一些解析器類來解析各種文檔格式,如表 3 所示。
表 3. Tika 解析器類
格式 | 描述 |
---|---|
Microsoft® Excel® (application/vnd.ms-excel) | 在所有的 Tika 版本中都有對 Excel 電子數據表的支持,基於的是 POI 的 HSSF 庫。 |
Microsoft Word®(application/msword) | 在所有的 Tika 版本中都有對 Word 文檔的支持,基於的是 POI 的 HWPF 庫。 |
Microsoft PowerPoint® (application/vnd.ms-powerpoint) | 在所有的 Tika 版本中都有對 PowerPoint 演示的支持,基於的是 POI 的 HSLF 庫。 |
Microsoft Visio® (application/vnd.visio) | 在 Tika V0.2 中加入了對 Visio 圖表的支持,基於的是 POI 的 HDGF 庫。 |
Microsoft Outlook® (application/vnd.ms-outlook) | 在 Tika V0.2 中加入了對 Outlook 消息的支持,基於的是 POI 的 HSMF 庫。 |
GZIP 壓縮 (application/x-gzip) | 在 Tika V0.2 中加入了對 GZIP 的支持,基於的是 Java 5 類庫中的 GZIPInputStream 類。 |
bzip2 壓縮 (application/x-bzip) | 在 Tika V0.2 中加入了對 bzip2 的支持,基於的是 Apache Ant 的 bzip2 解析代碼,而它最初基於的是 Aftex Software 的 Keiron Liddle 的工作成果。 |
MP3 音頻(audio/mpeg) | 在 Tika V0.2 中加入了對 MP3 文件的 ID3v1 標記的解析。如果找到,如下的元數據將被提取並設置:
|
MIDI 音頻 (audio/midi) | Tika 使用 javax.audio.midi 內的 MIDI 支持來解析 MIDI 序列文件。很多卡拉 OK 文件格式都基於的是 MIDI 並包含嵌入文本歌曲形式的歌詞,並且 Tika 知道該如何提取。 |
Wave 音頻 (audio/basic) | Tika 通過 javax.audio.sampled 包支持取樣的 wave 音頻(.wav 文件等)。只有取樣元數據才被提取。 |
Extensible Markup Language (XML) (application/xml) | Tika 使用 javax.xml 類解析 XML 文件。 |
HyperText Markup Language (HTML) (text/html) | Tika 使用 CyberNeko 庫解析 HTML 文件。 |
圖像 (image/*) | Tika 使用 javax.imageio 類從圖像文件中提取元數據。 |
Java 類文件 | Java 類文件的解析基於的是 ASM 庫以及 JCR-1522 的 Dave Brosius 的工作成果。 |
Java Archive Files | JAR 文件的解析是綜合使用 ZIP 和 Java 這兩種類文件解析器完成的。 |
OpenDocument (application/vnd.oasis.opendocument.*) | Tika 使用 Java 語言中的內置 ZIP 和 XML 特性來解析多為 OpenOffice V2.0 或更高版本所用的 OpenDocument 文檔類型。較早的 OpenOffice V1.0 格式也受支持,但它們目前不能像較新的格式那樣被自動檢測。 |
純文本 (text/plain) | Tika 使用 International Components for Unicode Java 庫(ICU4J)來解析純文本。 |
Portable Document Format (PDF) (application/pdf) | Tika 使用 PDFBox 庫來解析 PDF 文檔。 |
Rich Text Format (RTF) (application/rtf) | Tika 使用 Java 的內置 Swing 庫來解析 RTF 文檔。 |
TAR (application/x-tar) | Tika 使用來自 Apache Ant 的 TAR 解析代碼的調整版本來解析 TAR 文件。而此 TAR 代碼基於的是 Timothy Gerard Endres 的工作成果。 |
ZIP (application/zip) | Tika 使用 Java 的內置 ZIP 類來解析 ZIP 文件。 |
您可以使用您自己的解析器來擴展 Apache Tika,您對 Tika 所做的任何貢獻都是受歡迎的。Tika 的目標是盡可能地重用現有的解析器庫(比如 Apache PDFBox 或 Apache POI),因此 Tika 內的大多數解析器類都是適應於這些外部庫。Apache Tika 還包含一些不針對任何特定文檔格式的通用解析器實現。其中最值得一提的是 AutoDetectParser
類,它將所有的 Tika 功能包裝進一個能處理任何文檔類型的解析器。這個解析器可自動決定入向文檔的類型,然后會相應解析此文檔。現在,我們可以進行一些實際操作了。如下的這些類是我們在整個教程中要開發的:
BudgetScramble
— 顯示了如何使用 Apache Tika 元數據來決定哪個文檔最近被更改以及在何時更改。TikaMetadata
— 顯示了如何獲得某個文檔的所有 Apache Tika 元數據,即便沒有數據(只顯示所有的元數據類型)。TikaMimeType
— 顯示了如何使用 Apache Tika 的 mimetypes 來檢測某個特定文檔的 mimetype。TikaExtractText
— 顯示了 Apache Tika 的文件提取功能並將所提取的文本保存為合適的文件。LanguageDetector —
介紹了 Nutch 語言的識別功能來識別特定內容的語言。Summary —
總結了 Tika 特性,比如MimeType
、內容 charset 檢測和元數據。此外,它還引入了 cpdetector 功能來決定一個文件的 charset 編碼。最后,它顯示了 Nutch 語言識別的實際使用。
3 Tika文本抽取實例分析
Tika主要通過5個部分完成常規數據抽取:
1 InputStream input=new FileInputStream(new File("./myfile/Active Learning.pdf")); //構建InputStream來讀取數據,可以寫文件路徑,pdf,word,html等
2 BodyContentHandler textHandler=new BodyContentHandler(); //獲取內容
3 Metadata matadata=new Metadata();//Metadata對象保存了作者,標題等元數據
4 PDFParser ParseContext context=new ParseContext(); //這里Parser解析器根據不同文件采用不同解析器
5 Parser parser=new AutoDetectParser();//當調用parser,AutoDetectParser會自動估計文檔MIME類型,此處輸入pdf文件,因此可以使用
6 parser.parse(input, textHandler, matadata, context);//執行解析過程
源碼:
/** * Tika AutoDetectParser類來識別和抽取內容 * @throws TikaException * @throws SAXException * @throws IOException */ public static void getTextFronPDF() throws IOException, SAXException, TikaException{ //構建InputStream來讀取數據 InputStream input=new FileInputStream(new File("./myfile/Active Learning.pdf"));//可以寫文件路徑,pdf,word,html等 BodyContentHandler textHandler=new BodyContentHandler(); Metadata matadata=new Metadata();//Metadata對象保存了作者,標題等元數據 Parser parser=new AutoDetectParser();//當調用parser,AutoDetectParser會自動估計文檔MIME類型,此處輸入pdf文件,因此可以使用PDFParser ParseContext context=new ParseContext(); parser.parse(input, textHandler, matadata, context);//執行解析過程 input.close(); System.out.println("Title: "+matadata.get(Metadata.TITLE)); System.out.println("Type: "+matadata.get(Metadata.TYPE)); System.out.println("Body: "+textHandler.toString());//從textHandler打印正文 }
運行結果:
4 參考文獻和JAR包共享
相關文章
【文本處理】自然語言處理在現實生活中運用
【文本處理】多種貝葉斯模型構建及文本分類的實現
【文本處理】快速了解什么是自然語言處理
【文本處理】領域本體構建方法概述