2017-01-25 4 views
1

私はNodeでWebスクレーパーを作成し、CheerioやJSDomのようなモジュールを使ってHTMLを解析して一連のURLのDOMにすることを検討しています。しかし、私は必要な特定の機能を持っています。NodeJSの値で要素のCSSセレクタを取得するにはどうすればよいですか?

私の目的は、いくつかの重要な情報のためにサイト上に複数の類似したページを掻き集めることができるスクレーパーを構築することです。しかし、私はこれらの情報を含むサンプルデータをいくつか持っており、それらを使ってそれらのページのモデルを動的に作成し、そのモデルを使用して残りのサイトを削っていきたいと考えています。明確にするために

、それぞれが異なる製品を含むサイト上の3つのページがある場合:

ページ1:

<html> 
<body> 
<h1>Product 1</h1> 
<p>Desc</p> 
<small>$2.05</small> 
</body> 
</html> 

が2ページ:

<html> 
<body> 
<h1>Product 2</h1> 
<p>Desc</p> 
<small>$8.05</small> 
</body> 
</html> 

ページ3:

<html> 
<body> 
<h1>Product 3</h1> 
<p>Desc</p> 
<small>$5.07</small> 
</body> 
</html> 

Sa y私はすでに最初の製品のデータを持っています(私は製品名、Desc、および価格を知っています)。最初のページを使用してこれらの要素のセレクタを取得し、それらのセレクタを使用して他のページのデータをスクラップします。

DOM内にタグの内容がある場合、どのようにしてその要素のCSSセレクタを取得できますか?たとえば:

<html> 
    <body> 
    <h1>Hello world</h1> 
    </body> 
</html> 

は、どのように私は、「Hello World」のような文字列でチェリオ/ JSDomを提供し、それは要素が存在するDOMでのCSSセレクタを返すことができますか?

これを行う簡単な方法(別のフレームワークの使用を含む)がありますか、DOMオブジェクト全体をループして各要素の値を個別にチェックする唯一の方法ですか?

+0

同じノードリストを返す複数の異なるXPathが存在します。あなたはどれが欲しいですか?私は '// * [text()= 'Hello world']'はあなたの後ろではないと思いますか? – OrangeDog

+0

あなたは何を探したいですか?あなたはXPathを '// * [。 = "Hello world"] ' – skAstro

+0

" hello world "を含む要素が存在する要素/パスを見つけるだけで、そのパスを使用して後で他の情報を抽出することができます。基本的には、シードデータを使用してスクレイピングモデルを自動的に構築しています。 –

答えて

0

これはSAXモデルで達成するのが最も簡単で効率的ですが、代わりにDOMトラバーサルに適用できます。とにかくDOMを構築する必要がある場合は

var match, path = []; 

parser.on('start', function(tag) { currentPath.push(tag); }); 
parser.on('end', function(tag) { currentPath.pop(); }); 

parser.on('text', function(text) { 
    if (!match && text === 'Hello world') { 
    match = path.join('/'); 
    } 
}); 

、あなたは(内部だけで全体のDOMをループ)ノードは、ループアップ両親を見つけるために、XPathを使用することができます。

var path = []; 
var node = document.xpath('//*[.="Hello world"]')[0]; 

do { 
    path.push(node.tag); 
} while (node = node.parent); 

var match = path.reverse().join('/'); 

この第二の方法は、あなたが見つけるために多くの異なるノードを持っている場合は特に、多くの非効率的です。 SAXメソッドは、1回のパスですべてをカバーできますが、パーサーの実装に応じて不正な入力で苦労する可能性があります。

CSSセレクタの場合は、'/'' > 'に置き換えてください。

+0

あなたの最初の提案では、パーサオブジェクトは何ですか?あなたのコードが何をしているのかをより包括的にレビューできますか? –

+0

これはSAXパーサーです。おそらく何らかの種類の 'Stream'を使って応答をパイプすることができますし、' EventEmitter'はDOMを実行させることができます。 – OrangeDog

+0

私はちょうどCSSセレクタについて質問するために私の質問を修正しました。あなたのSAXソリューションはまだ適用されますか? –

関連する問題