0

目前,我正在尝试使用以下查询从某些网站上抓取表单:

select * from html 
where url="http://somedomain.com" 
and xpath="//form[@action]"

这将返回如下结果:

{
    form: {
        action: "/some/submit",
        id: "someId",
        div: {
            input: [
               ... some input elements here
            ]
        }
        fieldset: {
            div: {
                input: [
                    ... some more input elements here
                ]
            }
        }
    }
}

在某些站点上,这可能会深入很多层次,因此我不确定如何开始尝试过滤掉结果中不需要的元素。如果我可以在这里过滤掉它们,那么它会使我的后端代码更简单。基本上,我只喜欢表单和任何标签、输入、选择(和选项)和 textarea 后代。

这是我尝试过的 XPath 查询,但我意识到元素层次结构不会被维护,如果页面上有多个表单,这可能会导致问题:

//form[@action]/descendant-or-self::*[self::form or self::input or self::select or self::textarea or self::label]

但是,我确实注意到此查询返回的元素不再在 div 和表单下的其他元素下返回。

4

2 回答 2

1

我认为您尝试过的简单查询是不可能的。

但是,创建一个包含一些执行您正在寻找的过滤的 JavaScript 的新数据表并不会做太多工作。

数据表

一个快速的<execute>小块可能如下所示。

var elements = y.query("select * from html where url=@u and xpath=@x", {u: url, x: xpath}).results.elements();
var results = <url url={url}></url>;
for each (element in elements) {
    var result = element.copy();
    result.setChildren("");
    result.normalize();
    for each (descendant in y.xpath(element, filter)) {
        result.node += descendant;
    }
    results.node += result;
}
response.object = results;

» 查看完整的示例数据表

示例查询

use "store://VNZVLxovxTLeqYRH6yQQtc" as example;
select * from example where url="http://www.yahoo.com"

»在 YQL 控制台中查看此查询

示例结果

查询结果 XML

希望以上是朝着正确方向迈出的一步,并且看起来不会太令人生畏。

链接

于 2013-03-08T22:52:20.990 回答
0

这就是我过滤特定节点但仍允许显示所有属性的父标记的方式:

//form[@name]/@* | //form[@action]/descendant-or-self::node()[name()='input' or name()='select' or name()='textarea' or name()='label']

如果页面上有多个表单标签,它们应该按此父标签分组,而不是全部挤在一起且无法识别。

如果它有助于您希望节点出现的方式,您也可以反转联合:

//form[@action]/descendant-or-self::node()[name()='input' or name()='select' or name()='textarea' or name()='label'] | //form[@name]/@*
于 2013-03-06T14:44:59.927 回答