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

一部のサイトでは、これが何層も深くなる可能性があるため、結果から不要な要素を除外する方法がわかりません。ここでそれらを除外できれば、バックエンド コードがはるかに簡単になります。基本的には、フォームとラベル、入力、選択 (およびオプション)、およびテキストエリアの子孫が欲しいだけです。

これは私が試した 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 に答える