2013-04-15 40 views
5

xpathで要素を取得する関数をnode.jsに書き込もうとしています。xpathとcheerioを使って要素を取得する

私はチェリオ経由FSモジュール(私はこのWebページをローカルに保存されている必要があるため)私のDOMがにロードされている

xpath = '/html/body/div/div[2]/div/h1/span' 

のような希望のDOM要素のXPathを持っている:

var file = fs.readFileSync("aaa.html") 
var inDom = cheerio.load(file) 

その後私は各xpath部分を繰り返して、DOMツリーの要素を取得し、名前と要素番号が一致する場合は子要素をチェックし、そうであればrezをこのマテ要素のelemenとして格納しようとしています。 t。それから私は新しいxpathの部分で掘り下げ続けます。コードはこのように見えますが、最初のマッハを取得してすぐにrezを一致要素として設定すると、次のループサイクルでこの新しい要素が子要素を持たないように見えます。

var rez = inDom('html'); 
var xpath = inXpath.split("/"); 
for(var i = iterateStart; i < xpath.length; i++) { 
    var selector = xpath[ i ].split('[')[0]; 
    var matches = xpath[ i ].match(/\[(.*?)\]/); 
    var child = 0; 
    if(matches) { 
     child = matches[ 1 ]; 
    } 

    for(var k = 0; k < rez.length; k++) { 
     var found = false 
     var curE = rez[ k ] 

     for(var p = 0; p < curE.children.length; p++) { 
      var curE_child = curE.children[ p ] 

      if(curE_child.name = selector) { 
       if(child > 0) { 
        child-- 
       } 
       else { 
        rez = curE_child 
        found = true 
        break 
       } 
      }    
     } 
     if(found) { 
      break 
     } 
    }  
} 

上記のnode.jsモジュールを使用してコードを教えてもらえますか?

答えて

4

あなたは、より多くの作業をしているように見えますし、希望する要素を見つける必要があります。サンプルのhtmlページを投稿できますか?

Cheerioは、使用すべき要素を見つけるためのより高いレベルのAPIを提供します。

var html = fs.readFileSync('aaa.html') 
var $ = cheerio.load(html) 
var selector = 'div' // some selector here which I can tune to the example html page 
var parent = $(selector) 
var childSelector = 'p' // some other selector 
var children = parent.find(childSelector) 
+0

、3番目の要素、xpathの部分が '../ div [3]/...'のようなものであるとき。私はここに貼り付けたコードを使用します。http://pastebin.com/pzSYz6Zcエラーも貼り付けられます。 – Astro

+0

サンプルHTMLなしでは、あなたに提案をするのは難しいです。 htmlページの例を投稿してください – Noah

+0

htmlページはありません、それはnode.jsコードの一部です。 – Astro

0

Iはxpath所与、cheerioに正しい要素を取得し、このコードを書かれています。

これは、最も基本的なxpath、質問で言及されている種類、およびブラウザで通常要素に与えられている種類に対してのみ機能します。

inXpath = "BODY/DIV[1]/DIV[2]/DIV[1]/DIV[1]/DIV[3]/DIV[1]/DIV[1]/DIV[3]/DIV[3]/DIV[1]/DIV[1]/DIV[1]/DIV[1]/SPAN[1]" 
var xpath = inXpath.split("/"); 
var dom_body = cheerio.load(body); 
sss = dom_body('*'); 
for(var i = 0; i < xpath.length; i++) { 
    if (xpath[i].indexOf('[') == -1){ 
     sss = sss.children(xpath[i]) 
    } else { 
     var selector = xpath[i].split('[')[0]; 
     var matches = xpath[i].match(/\[(.*?)\]/); 
     var index = matches[1] - 1; 
     sss = sss.children(selector).eq(index) 
    } 
} 
console.log(sss.html().trim()) 
+0

しかし、W3Cに準拠したXPathの実装のようには思えません。 –

0

はいXPathの実装があります:

npm install xpath 

サンプル:

var xml = "<book><title>Harry Potter</title></book>" 
var doc = new dom().parseFromString(xml) 
var title = xpath.select("//title/text()", doc).toString() 
console.log(title) 

出典:私はあなたのアプローチを実装した、と私は例えば、取得に貼り付け https://www.npmjs.org/package/xpath

+1

残念ながら、例(xmldom)で使用されているDOMパーサーは非常に厳格で、実際のHTMLページではうまく機能しません。 私はまだxpathと互換性のある寛容なDOMパーサーを見つけられませんでした。 –

関連する問題