java tika如何将html转换为保留特定元素的纯文本

标签 java apache-tika

下面的代码可以完美地将 html 转换为纯文本...

Url url = new URL(your_url);
InputStream is = url.openStream(); 
ContentHandler textHandler = new BodyContentHandler();
Metadata metadata = new Metadata();
AutoDetectParser parser = new AutoDetectParser();
ParseContext context = new ParseContext();
parser.parse(is, textHandler, metadata, context);
System.out.println("Body: " + textHandler.toString());

我的问题是: 如何保留/保留特定元素(如链接等)...或如何防止特定元素(如链接)在 html 到纯文本转换中被删除?

谢谢并致以最诚挚的问候...

最佳答案

您可以通过多种方式使用 Apache Tika 来完成此类工作。

正如 Gagravarr 所说,您使用的 ContentHandler 是这里的关键。有许多有用的工具可以在这里提供帮助,或者您也可以构建自己的自定义工具。

由于我不确定您想要做什么,因此我尝试分享一些常见方法的示例,尤其是 HTML 内容。

匹配内容处理程序

常见的途径是使用 MatchingContentHandler 来过滤您感兴趣的内容:

URL url = new URL("http://tika.apache.org");
InputStream is = url.openStream();

// Only select <a> tags to be output
XPathParser xhtmlParser = new XPathParser("xhtml", XHTMLContentHandler.XHTML);
Matcher divContentMatcher = xhtmlParser.parse("//xhtml:a/descendant::node()");
MatchingContentHandler handler = new MatchingContentHandler(new ToHTMLContentHandler(), divContentMatcher);

// Parse based on original question
HtmlParser parser = new HtmlParser()
Metadata metadata = new Metadata();
parser.parse(is, handler, metadata, new ParseContext());
System.out.println("Links: " + handler.toString());

值得注意的是,这仅用于包含并且仅支持 XPath 的子集。请参阅XPathParser了解详情。

LinkContentHandler

如果您只想提取链接,LinkContentHandler 是一个不错的选择:

URL url = new URL("http://tika.apache.org");
InputStream is = url.openStream();
LinkContentHandler linkHandler = new LinkContentHandler();
Metadata metadata = new Metadata();
HtmlParser parser = new HtmlParser();
parser.parse(is, linkHandler, metadata, new ParseContext());
System.out.println("Links: " + linkHandler.getLinks());

它的代码也是如何构建自定义处理程序的一个很好的示例。

BoilerpipeContentHandler

BoilerpipeContentHandler 使用底层的 Boilerpipe 库,允许您使用它定义的提取器之一来处理内容。

URL url = new URL("http://tika.apache.org");
InputStream is = url.openStream();

ExtractorBase extractor = ArticleSentencesExtractor.getInstance();
BoilerpipeContentHandler textHandler = new BoilerpipeContentHandler(new BodyContentHandler(), extractor);

Metadata metadata = new Metadata();
HtmlParser parser = new HtmlParser();
parser.parse(is, textHandler, metadata, new ParseContext());

System.out.println(textHandler.getTextDocument().getTextBlocks());

如果您对里面的内容真的感兴趣,这些非常有用,因为提取器可以帮助您专注于内容。

自定义 ContentHandler 或 ContentHandlerDecorator

您可以构建自己的ContentHandler来进行自定义处理并从文件中准确获取您想要的内容。

在某些情况下,这可能是写出特定内容,例如下面的示例,或者在其他情况下,它可能是在进行处理,例如收集和提供可用链接,如 LinkHandler 中。

使用自定义 ContentHandler 实例非常强大,Apache Tika 代码库以及其他开源项目中提供了大量示例。

下面是一个人为的示例,只是尝试发出部分 HTML:

URL url = new URL("http://tika.apache.org");
InputStream is = url.openStream();

StringWriter sw = new StringWriter();
SAXTransformerFactory factory = (SAXTransformerFactory) SAXTransformerFactory.newInstance();
TransformerHandler handler = factory.newTransformerHandler();
handler.getTransformer().setOutputProperty(OutputKeys.METHOD, "html");
handler.setResult(new StreamResult(sw));

ContentHandlerDecorator h2Handler = new ContentHandlerDecorator(handler) {
    private final List<String> elementsToInclude = List.of("h2");
    private boolean processElement = false;

    @Override
    public void startElement(String uri, String local, String name, Attributes atts)
            throws SAXException {
        if (elementsToInclude.contains(name)) {
            processElement = true;
            super.startElement(uri, local, name, atts);
        }
    }

    @Override
    public void ignorableWhitespace(char[] ch, int start, int length) {
        // Skip whitespace
    }

    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
        if (!processElement) {
            return;
        }
        super.characters(ch, start, length);
    }

    @Override
    public void endElement(
            String uri, String local, String name) throws SAXException {
        if (elementsToInclude.contains(name)) {
            processElement = false;
            super.endElement(uri, local, name);
        }
      }
};

HtmlParser parser = new HtmlParser();
parser.parse(is, h2Handler, new Metadata(), new ParseContext());
System.out.println("Heading Level 2s: " + sw.toString());

正如您在其中一些示例中看到的,一个或多个 ContentHandler 实例可以链接在一起,但值得注意的是,有些人希望输出格式正确,因此请检查 Javadocs。如果您想将不同的文件映射为您自己的通用格式,XHTMLContentHandler 也很有用。

JSoup:)

另一条路线是JSoup ,如果您直接处理 HTML,则可以直接(跳过 Tika 部分并使用 Jsoup.connect()),如果您想读取从不同文件类型生成的 HTML,则可以与 Apache Tika 链接。

URL url = new URL("http://tika.apache.org");
InputStream is = url.openStream();
ToHTMLContentHandler html = new ToHTMLContentHandler();
HtmlParser parser = new HtmlParser();
parser.parse(is, html, new Metadata(), new ParseContext());
Document doc = Jsoup.parse(html.toString());
Elements h2List = doc.select("h2");
for (Element headline : h2List) {
    System.out.println(headline.text());
}   

解析完后,您可以使用 Jsoup 查询该文档。与为该作业构建的 ContentHandler 相比,这不是最有效的,但对于困惑的内容集可能很有​​用。

关于java tika如何将html转换为保留特定元素的纯文本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64644334/

相关文章:

java - JTextArea 到 ScrollPane 不起作用

java - 加载内存Bitmap并共享

java - 是否可以使用java中的apache tika从excel表(从列或行)中获取特定数据?

java - 使用 Tika 解析元标记并从正文中获取 HTML 内容

java - 如何利用以下 ECM 技术 - 比较

image - 使用 Apache Tika 从 PDF 中提取图像

java - 没有 JAAS 的 Kerberos 身份验证?

java - 通过套接字发送对象导致 SocketException

solr - 如何使用 apache solr 索引文本文件

java - 玩 2.0+Java 与玩 2.0+Scala?