基于XPATH的内容从html页面中提取

时间:2010-07-29 14:40:03

标签: java sax xpath

我试图根据给定的xpath提取内容。当它只是我想要提取的一个元素时,没有问题。当我有一个匹配该xpath的项目列表时,我得到节点列表,我可以提取值。

但是,有几个项目相互关联形成一个组,并且该组重复自己。

我能做的一种方法是获取所有这些组的父节点的节点列表,然后应用基于SAX的解析技术来提取信息。但这将引入特定于模式的编码。我想让它变得通用。 离。

<html><body>
<!--... a lot divs and other tags ... -->
<div class="divclass">
<item>
     <item_name>blah1</item_name>
     <item_qty>1</item_qty>
     <item_price>100</item_price>
</item>
</div>
<div class="divclass">
<item>
     <item_name>blah2</item_name>
     <item_qty>2</item_qty>
     <item_price>200</item_price>
</item>
</div>
<div class="divclass">
<item>
     <item_name>blah3</item_name>
     <item_qty>3</item_qty>
     <item_price>300</item_price>
</item>
</div>
</body></html>

我可以轻松编写 this xml的代码,但不能编写可以解析任何给定规范的通用代码。

我应该能够从上方创建list map attribute-value

有没有人试过这个?

修改 输入xpath列表:

1. "html:div[@class='divclass']/item/item_name"
2. "html:div[@class='divclass']/item/item_qty"
3. "html:div[@class='divclass']/item/item_price"

简单文本中的预期输出:

 item_name:blah1;item_qty:1;item_price:100
 item_name:blah2;item_qty:2;item_price:200
 item_name:blah3;item_qty:3;item_price:300

这里的关键点是,如果我单独应用每个xpath,它将垂直取出结果,即第一个将获取所有item_names,第二个将获取所有qtys。所以我将放松这些内容中的相互关系。

希望这能清除我的要求。

由于 Nayn

5 个答案:

答案 0 :(得分:3)

我不确定我是否提出了您的问题,但听起来您想在HTML文档上使用XPath。

要使用XPath,需要精心构建的HTML文档。 Java有几种HTML解析器; this article比较其中4个。

HtmlCleaner似乎提供了你想要的东西。它允许在“清理的”HTML文档上执行XPath的子集。显然它不支持完整的XPath表达式,请参阅the documentation

如果您需要比HtmlCleaner支持的更复杂的XPath表达式,则可能需要将javax.xml.xpath包与格式良好的XHTML文档一起使用。 JTidy可以将HTML文档转换为XHTML文档。

我希望这能回答你的问题。

答案 1 :(得分:2)

我认为XQuery是屏幕抓取的绝佳解决方案。您可以使用Saxon处理器来执行xqueries。此外,您可以使用Piggy Bank Firefox扩展来轻松找到关于要从网页中提取的内容的XPath表达式,您可以在xqueries中使用它。

答案 2 :(得分:1)

为什么不分两步应用XPath。

首先获取记录的XPath(输出中的行):

//div[@class='divclass']/item

然后XPath(s)获取相对于每条记录的字段(列):

item_name
item_qty
item_price

这是工作代码(在Javascript,Windows脚本中),为您提供所需的输出:

var doc = new ActiveXObject("MSXML.DOMDocument");
doc.load("test.xml");

// XPATH #1
var recordXPath = "//div[@class='divclass']/item";
// XPATHS #2, in a dictionary ("field name":"XPath")
var fieldXPaths = { item_name : "item_name",
                    item_qty : "item_name",
                    item_price : "item_price" };

var items = doc.selectNodes(recordXPath);
for (var itemCtr = 0; itemCtr < items.length; itemCtr++) {
    var item = items[itemCtr];
    var fieldEntries = [];

    for (var fieldName in fieldXPaths) {
        var fieldXPath = fieldXPaths[fieldName];
        var fieldNode = item.selectSingleNode(fieldXPath);
        fieldEntries.push(fieldNode.tagName + ":" + fieldNode.text);
    }
    WScript.Echo(fieldEntries.join(";"));
}

答案 3 :(得分:0)

我不明白你想要实现什么以及它与XPath的关系。如果要将XML映射到Java对象,那么JAXB可能有所帮助,但它基于XML模式,而不是基于XPath。

答案 4 :(得分:0)

我不知道这是否有帮助,但我使用XSLT从数据转向HTML。在我看来,你只需要稍微构建一下XPATH执行,而XSLT对此有好处。