Inhaltsanalyse mit Apache Tika

Inhaltsanalyse mit Apache Tika

1. Überblick

Apache Tika is a toolkit for extracting content and metadata from various types of documents wie Word, Excel und PDF oder sogar Multimediadateien wie JPEG und MP4.

Alle textbasierten und multimedialen Dateien können über eine gemeinsame Oberfläche analysiert werden, wodurch Tika zu einer leistungsstarken und vielseitigen Bibliothek für die Inhaltsanalyse wird.

In diesem Artikel geben wir eine Einführung in Apache Tika, einschließlich der Parsing-API und der automatischen Erkennung des Inhaltstyps eines Dokuments. Arbeitsbeispiele werden ebenfalls bereitgestellt, um die Operationen dieser Bibliothek zu veranschaulichen.

2. Anfangen

Um Dokumente mit Apache Tika zu analysieren, benötigen wir nur eine Maven-Abhängigkeit:


    org.apache.tika
    tika-parsers
    1.17

Die neueste Version dieses Artefakts befindet sich inhere.

3. DieParser API

The Parser API is the heart of Apache Tika, abstracting away the complexity of the parsing operations. Diese API basiert auf einer einzigen Methode:

void parse(
  InputStream stream,
  ContentHandler handler,
  Metadata metadata,
  ParseContext context)
  throws IOException, SAXException, TikaException

Die Parameter dieser Methode haben folgende Bedeutung:

  • stream eineInputStream Instanz, die aus dem zu analysierenden Dokument erstellt wurde

  • handler aContentHandler Objekt, das eine Folge von XHTML SAX-Ereignissen empfängt, die aus dem Eingabedokument analysiert wurden; Dieser Handler verarbeitet dann Ereignisse und exportiert das Ergebnis in eine bestimmte Form

  • metadata aMetadata Objekt, das Metadateneigenschaften in und aus dem Parser überträgt

  • context eineParseContext-Instanz mit kontextspezifischen Informationen, die zum Anpassen des Analyseprozesses verwendet werden

Die Methodeparse löst einIOException aus, wenn sie nicht aus dem Eingabestream lesen kann, einTikaException, wenn das aus dem Stream entnommene Dokument nicht analysiert werden kann, und einSAXException, wenn der Handler kann ein Ereignis nicht verarbeiten.

Beim Parsen eines Dokuments versucht Tika, vorhandene Parser-Bibliotheken wie Apache POI oder PDFBox so weit wie möglich wiederzuverwenden. Infolgedessen sind die meisten Implementierungsklassen vonParsernur Adapter für solche externen Bibliotheken.

In Abschnitt 5 erfahren Sie, wie die Parameterhandler undmetadata zum Extrahieren von Inhalten und Metadaten eines Dokuments verwendet werden können.

Der Einfachheit halber können wir die FassadenklasseTika verwenden, um auf die Funktionalität derParser-API zuzugreifen.

4. Automatische Erkennung

Apache Tika kann den Typ eines Dokuments und seine Sprache automatisch anhand des Dokuments selbst und nicht anhand zusätzlicher Informationen erkennen.

4.1. Dokumenttyperkennung

The detection of document types can be done using an implementation class of the Detector interface, die eine einzige Methode hat:

MediaType detect(java.io.InputStream input, Metadata metadata)
  throws IOException

Diese Methode verwendet ein Dokument und die zugehörigen Metadaten und gibt dann einMediaType-Objekt zurück, das die beste Vermutung hinsichtlich des Dokumenttyps beschreibt.

Metadaten sind nicht die einzige Informationsquelle, auf die sich ein Detektor stützt. Der Detektor kann auch magische Bytes verwenden, die ein spezielles Muster am Anfang einer Datei darstellen, oder den Erkennungsprozess an einen geeigneteren Detektor delegieren.

Tatsächlich ist der vom Detektor verwendete Algorithmus von der Implementierung abhängig.

Beispielsweise arbeitet der Standarddetektor zuerst mit magischen Bytes und dann mit Metadateneigenschaften. Wenn der Inhaltstyp zu diesem Zeitpunkt noch nicht gefunden wurde, erkennt er mithilfe des Service Loaders alle verfügbaren Detektoren und probiert sie nacheinander aus.

4.2. Spracherkennung

Zusätzlich zum Typ eines Dokuments kann Tika seine Sprache auch ohne Hilfe von Metadateninformationen identifizieren.

In früheren Versionen von Tika wurde die Sprache des Dokuments mithilfe einerLanguageIdentifier-Instanz erkannt.

LanguageIdentifier wurde jedoch zugunsten von Webdiensten abgelehnt, was in den Dokumenten vonGetting Started nicht klargestellt wird.

Spracherkennungsdienste werden jetzt über Untertypen der abstrakten KlasseLanguageDetector bereitgestellt. Mithilfe von Webdiensten können Sie auch auf vollwertige Online-Übersetzungsdienste wie Google Translate oder Microsoft Translator zugreifen.

Der Kürze halber werden wir diese Dienste nicht im Detail behandeln.

5. Tika in Aktion

In diesem Abschnitt werden die Funktionen von Apache Tika anhand von Arbeitsbeispielen erläutert.

Die Illustrationsmethoden werden in eine Klasse eingeschlossen:

public class TikaAnalysis {
    // illustration methods
}

5.1. Dokumenttypen erkennen

Hier ist der Code, mit dem wir den Typ eines ausInputStream gelesenen Dokuments ermitteln können:

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();
}

Angenommen, wir haben eine PDF-Datei mit dem Namentika.txt im Klassenpfad. Die Erweiterung dieser Datei wurde geändert, um zu versuchen, unser Analysetool auszutricksen. Der tatsächliche Typ des Dokuments kann weiterhin durch einen Test gefunden und bestätigt werden:

@Test
public void whenUsingDetector_thenDocumentTypeIsReturned()
  throws IOException {
    InputStream stream = this.getClass().getClassLoader()
      .getResourceAsStream("tika.txt");
    String mediaType = TikaAnalysis.detectDocTypeUsingDetector(stream);

    assertEquals("application/pdf", mediaType);

    stream.close();
}

Es ist klar, dass eine falsche Dateierweiterung Tika nicht davon abhalten kann, den richtigen Medientyp zu finden, dank der magischen Bytes%PDF am Anfang der Datei.

Der Einfachheit halber können wir den Erkennungscode mithilfe der FassadenklasseTikamit demselben Ergebnis neu schreiben:

public static String detectDocTypeUsingFacade(InputStream stream)
  throws IOException {

    Tika tika = new Tika();
    String mediaType = tika.detect(stream);
    return mediaType;
}

5.2. Inhalte extrahieren

Extrahieren wir nun den Inhalt einer Datei und geben das Ergebnis alsString zurück - unter Verwendung derParser-API:

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();
}

Geben Sie eine Microsoft Word-Datei im Klassenpfad mit folgendem Inhalt an:

Apache Tika - a content analysis toolkit
The Apache Tika™ toolkit detects and extracts metadata and text ...

Der Inhalt kann extrahiert und überprüft werden:

@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();
}

Auch hier kann die KlasseTikaverwendet werden, um den Code bequemer zu schreiben:

public static String extractContentUsingFacade(InputStream stream)
  throws IOException, TikaException {

    Tika tika = new Tika();
    String content = tika.parseToString(stream);
    return content;
}

5.3. Metadaten extrahieren

Zusätzlich zum Inhalt eines Dokuments kann dieParser-API auch Metadaten extrahieren:

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;
}

Wenn im Klassenpfad eine Microsoft Excel-Datei vorhanden ist, bestätigt dieser Testfall, dass die extrahierten Metadaten korrekt sind:

@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("Author"));

    stream.close();
}

Zum Schluss noch eine andere Version der Extraktionsmethode unter Verwendung der FassadenklasseTika:

public static Metadata extractMetadatatUsingFacade(InputStream stream)
  throws IOException, TikaException {
    Tika tika = new Tika();
    Metadata metadata = new Metadata();

    tika.parse(stream, metadata);
    return metadata;
}

6. Fazit

Dieses Tutorial konzentrierte sich auf die Inhaltsanalyse mit Apache Tika. Using the Parser and Detector APIs, we can automatically detect the type of a document, as well as extract its content and metadata.

Für erweiterte Anwendungsfälle können wir benutzerdefinierte KlassenParser undDetector erstellen, um mehr Kontrolle über den Analyseprozess zu haben.

Den vollständigen Quellcode für dieses Tutorial finden Sie unterover on GitHub.