使用Apache Tika实现内容分析
使用Apache Tika實(shí)現(xiàn)內(nèi)容分析
Apache Tika可以抽取不同類型的內(nèi)容和元信息的開源工具,如word、excel、pdf,甚至多媒體文件如JPEG、MP4。所有基于文本的和多媒體文件都可以使用通用接口進(jìn)行解析,這使得Tika成為功能強(qiáng)大且用途廣泛的內(nèi)容分析庫(kù)。
本文將介紹Apache Tika,包括解析API、如何自動(dòng)監(jiān)測(cè)文檔內(nèi)容類型,同時(shí)提供示例說(shuō)明。
引用類庫(kù)
為了使用Apache Tika,我們需要通過(guò)maven引入依賴:
<dependency><groupId>org.apache.tika</groupId><artifactId>tika-parsers</artifactId><version>1.17</version> </dependency>讀者可以查找合適的版本。
解析API
解析API是Tika的核心功能,抽象解析操作的復(fù)雜性,僅依賴單個(gè)方法:
void parse(InputStream stream, ContentHandler handler, Metadata metadata, ParseContext context) throws IOException, SAXException, TikaException我們簡(jiǎn)要解釋方法參數(shù):
- stream,從需要被解析文檔創(chuàng)建的InputStream實(shí)例
- handler,接收從輸入文檔解析XHTML SAX事件序列的ContentHandler對(duì)象,負(fù)責(zé)處理事件并以特定的形式導(dǎo)出結(jié)果。
- metadata,元數(shù)據(jù)對(duì)象,它在解析器中傳遞元數(shù)據(jù)屬性
- context,帶有上下文相關(guān)信息的ParseContext實(shí)例,用于自定義解析過(guò)程。
如果從輸入流讀取失敗,則parse方法拋出IOException異常,從流中獲取的文檔不能被解析拋TikaException異常,處理器不能處理事件則拋SAXException異常。
當(dāng)解析文檔時(shí),Tika盡量重用已經(jīng)存在的解析庫(kù),如Apache POI或PDFBox。因此,大多數(shù)解析器實(shí)現(xiàn)類僅適配這些外部類庫(kù)。下面,我們將了解如何使用處理程序和元數(shù)據(jù)參數(shù)來(lái)提取文檔的內(nèi)容和元數(shù)據(jù)。為了方便,我們能使用Tika的門面類調(diào)用解析器Api。
自動(dòng)監(jiān)測(cè)
Apache Tika可以根據(jù)文檔本身而無(wú)需額外信息則可以自動(dòng)檢測(cè)文檔的類型和語(yǔ)言。
檢測(cè)文檔類型
可以通過(guò)Detector接口的實(shí)現(xiàn)類檢測(cè)文檔類型,其僅有一個(gè)方法:
MediaType detect(java.io.InputStream input, Metadata metadata) throws IOException方法帶有文檔流和其元數(shù)據(jù)參數(shù),返回MediaType對(duì)象用于描述文檔最佳可能相關(guān)類型。
元數(shù)據(jù)并不是探測(cè)器所依賴的唯一信息來(lái)源,還可以使用對(duì)應(yīng)在文件開頭的特殊模式的魔術(shù)字節(jié),或者將檢測(cè)過(guò)程委托給更合適的檢測(cè)器。
事實(shí)上,探測(cè)器算法依賴實(shí)現(xiàn)。舉例說(shuō)明,默認(rèn)探測(cè)器首先使用魔術(shù)字節(jié),然后是元數(shù)據(jù)屬性。如果還不能獲得文檔類型,則使用service loader去發(fā)現(xiàn)所有有效的探測(cè)器,然后依次嘗試。
語(yǔ)言檢測(cè)
除了文檔類型之外,Tika還可以在沒有元數(shù)據(jù)信息的情況下識(shí)別它的語(yǔ)言。
Tika早期版本,使用LanguageIdentifier 實(shí)例檢測(cè)文檔語(yǔ)言。然而,LanguageIdentifier對(duì)于web服務(wù)的支持已經(jīng)被棄用。
語(yǔ)言檢測(cè)服務(wù)現(xiàn)在通過(guò)抽象類LanguageDetector的子類提供。使用web服務(wù),您還可以訪問(wèn)完全成熟的在線翻譯服務(wù),如谷歌翻譯或Microsoft Translator。為了簡(jiǎn)潔起見,我們不詳細(xì)討論這些服務(wù)。
Tika實(shí)戰(zhàn)舉例
本節(jié)通過(guò)示例描述Tika特性,示例方法封裝在類里:
public class TikaAnalysis {// illustration methods }檢測(cè)文檔類型
下面代碼可以檢測(cè)InputStream對(duì)應(yīng)文檔類型:
public static String detectDocTypeUsingDetector(InputStream stream) throws IOException {Detector detector = new DefaultDetector();Metadata metadata = new Metadata();MediaType mediaType = detector.detect(stream, metadata);return mediaType.toString(); }假設(shè)我們有一個(gè)pdf文件在類路徑下,擴(kuò)展名我們故意修改為txt去誤導(dǎo)tika,但實(shí)際真實(shí)類型仍然能被檢測(cè):
@Testpublic void whenUsingDetector_thenDocumentTypeIsReturned() throws IOException {InputStream stream = this.getClass().getClassLoader().getResourceAsStream("tika.txt");String mediaType = TikaAnalysis.detectDocTypeUsingDetector(stream);assertEquals("application/pdf", mediaType);stream.close();}很明顯,錯(cuò)誤的文件擴(kuò)展名沒能讓tika犯錯(cuò),因?yàn)閜df的魔術(shù)字節(jié)在pdf文件的開頭。
為了簡(jiǎn)潔,我們可以使用Tika的門面類重寫之前的方法:
抽取文檔內(nèi)容
下面我們使用Parser API抽取文件內(nèi)容,然后返回結(jié)果字符串:
public static String extractContentUsingParser(InputStream stream) throws IOException, TikaException, SAXException {Parser parser = new AutoDetectParser();ContentHandler handler = new BodyContentHandler();Metadata metadata = new Metadata();ParseContext context = new ParseContext();parser.parse(stream, handler, metadata, context);return handler.toString(); }類路徑下有word文檔,內(nèi)容如下:
Apache Tika - a content analysis toolkit The Apache Tika? toolkit detects and extracts metadata and text ...測(cè)試內(nèi)容代碼:
@Test public void whenUsingParser_thenContentIsReturned() throws IOException, TikaException, SAXException {InputStream stream = this.getClass().getClassLoader().getResourceAsStream("tika.docx");String content = TikaAnalysis.extractContentUsingParser(stream);assertThat(content, containsString("Apache Tika - a content analysis toolkit"));assertThat(content, containsString("detects and extracts metadata and text"));stream.close(); }當(dāng)然,使用Tika類會(huì)更方便:
public static String extractContentUsingFacade(InputStream stream) throws IOException, TikaException {Tika tika = new Tika();String content = tika.parseToString(stream);return content; }抽取元數(shù)據(jù)
除了文檔內(nèi)容,Parser API也能抽取元數(shù)據(jù):
public static Metadata extractMetadatatUsingParser(InputStream stream) throws IOException, SAXException, TikaException {Parser parser = new AutoDetectParser();ContentHandler handler = new BodyContentHandler();Metadata metadata = new Metadata();ParseContext context = new ParseContext();parser.parse(stream, handler, metadata, context);return metadata; }在類路徑下放一個(gè)tika.xlsx文件進(jìn)行單元測(cè)試:
@Test public void whenUsingParser_thenMetadataIsReturned() throws IOException, TikaException, SAXException {InputStream stream = this.getClass().getClassLoader().getResourceAsStream("tika.xlsx");Metadata metadata = TikaAnalysis.extractMetadatatUsingParser(stream);assertEquals("org.apache.tika.parser.DefaultParser", metadata.get("X-Parsed-By"));assertEquals("Microsoft Office User", metadata.get("creator"));stream.close(); }當(dāng)然,另一版本可以通過(guò)Tika類實(shí)現(xiàn):
public static Metadata extractMetadatatUsingFacade(InputStream stream) throws IOException, TikaException {Tika tika = new Tika();Metadata metadata = new Metadata();tika.parse(stream, metadata);return metadata; }總結(jié)
文本介紹了內(nèi)容分析工具Apache Tike。使用其Parser和Detechtor API,可以自動(dòng)檢測(cè)文檔類型,也可以抽取其內(nèi)容和元數(shù)據(jù)。對(duì)于特定場(chǎng)景,我們可以自定義Parser和Detechtor類實(shí)現(xiàn)更多解析過(guò)程控制。
總結(jié)
以上是生活随笔為你收集整理的使用Apache Tika实现内容分析的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 例题:索洛模型——弹性与收敛速度
- 下一篇: 如何进行在线教育app开发