2013-04-15 12 views
5

Provare a scrivere una funzione in node.js che otterrà l'elemento da xpath.Ottenere elemento usando xpath e cheerio

Ho un XPath dell'elemento DOM desiderato come

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

mio DOM è stato caricato in cheerio via fs modulo (perché ho il sito memorizzate localmente):

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

Poi Sto provando ad iterare attraverso ogni parte di xpath, ottenere l'elemento dell'albero dom, controllare che siano figli se il nome e il numero dell'elemento corrispondono, e se lo fanno, memorizza rez come questo elemen mathed t. Quindi continuo a scavare con la nuova parte xpath. Il codice appare come questo, ma non riesce a ottenere ciò che voglio perché appena ottengo il primo mach e impostato rez come elemento corrispondente, nel prossimo ciclo ciclo questo nuovo elemento sembra non avere alcun elemento figlio.

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

Qualcuno può aiutarmi con il codice utilizzando i moduli Node.JS menzionati?

risposta

4

Sembra che tu stia facendo molto più lavoro, quindi devi trovare l'elemento desiderato. Puoi pubblicare una pagina HTML di esempio?

Cheerio fornisce una API di livello superiore per la ricerca di elementi da utilizzare.

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

mi ha attuato il suo approccio, e ho attaccato su come ottenere, ad esempio, , terzo elemento, quando la parte di xpath è come '../ div [3]/...'. Uso il codice incollato qui http://pastebin.com/pzSYz6Zc Anche l'errore viene incollato. – Astro

+0

Senza esempi di codice HTML è difficile dare suggerimenti. Per favore pubblica una pagina html di esempio – Noah

+0

non c'è una pagina html, è una parte dal codice node.js – Astro

0

Ho scritto questo codice, che ottiene l'elemento corretto nel cheerio, dato un xpath.

Questo funziona solo per il più semplice xpath, il tipo menzionato nella domanda e il tipo che di solito viene dato dai browser per un elemento.

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

Tuttavia non sembra un'implementazione XPath conforme a W3C. –

0

sì, c'è implementazione XPath:

npm install xpath 

Esempio:

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) 

Fonte: https://www.npmjs.org/package/xpath

+1

Sfortunatamente il parser DOM utilizzato nell'esempio (xmldom) è molto rigido e non funziona bene con pagine HTML reali. Al momento non ho ancora trovato un parser DOM tollerante compatibile con xpath. –