0

我想从这个网站提取内容:https ://it.projektwerk.com/de/projects/

例如,我有一个 XPath 表达式:(.//*[@id='content_0']/H3/A 请注意,大写字母是正确的,因为我的文档解析器 -> org.cyberneko.html ...将标签解析为那些大写字母)

这是一个有效的 XPath 表达式;例如,我可以使用 FirePath 获取内容。但是,使用这些javax.xml.xpath类,检索是不可能的。我这样做是这样的:

XPath xpath = XPathFactory.newInstance().newXPath();
XPathExpression expr = xpath.compile(exprString);
Node node = expr.evaluate(doc, XPathConstants.NODE);

node总是null

我不明白这一点,因为还有其他网站具有相同语法的其他表达式,在哪里可以工作(例如.//*[@id='p_p_id']/DIV/DIV/DIV/DIV[3]/A/H3/SPAN

希望有人可以提供帮助。

4

1 回答 1

0

多亏了 VGR,我才能够了解问题所在。那些 Xpath 表达式不起作用的网站是一个命名空间感知网站,其 html 标记构造如下:

当我使用HtmlCleaner时,我使用了以下代码:

HtmlCleaner cleaner = new HtmlCleaner();
CleanerProperties props = cleaner.getProperties();
props.setNamespacesAware(false);
TagNode mainNode = cleaner.clean(htmlString);

根据文档,这应该从 html 文档中删除命名空间属性。但这不起作用!令人惊讶的是,被测试的 html 文档的 html 标记内的 xmlns 属性只会改变它在属性列表中的位置。因此解决方案是使用 html 节点的 HtmlCleaner 的 TagNode 表示手动从 htmlTag 中删除 xmlns 属性:

public TagNode removeNamespaceFromHtmlTag(TagNode htmlNode) {
    htmlNode.removeAttribute("xmlns");
    return htmlNode;
}

删除它,问题中定义的 XPath 表达式将返回所需的结果。

于 2016-10-05T08:13:27.977 回答