2013-04-15 24 views
5

Próba napisania funkcji w pliku node.js, która otrzyma element przez xpath.Uzyskiwanie elementu za pomocą xpath i cheerio

Mam XPath żądanego elementu DOM jak

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

Mój DOM załadowanego cheerio poprzez fs moduł (bo ta strona przechowywane lokalnie):

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

Następnie Próbuję iterować za pośrednictwem każdej części xpath, pobrać element drzewa dom, sprawdzić jego dzieci, jeśli nazwa i numer elementu pasują, a jeśli tak, to przechowywać rez jako ten mathed elemen t. Następnie kontynuuję pracę przy nowej części xpath. Kod wygląda tak, ale nie dostaje tego, czego chcę, ponieważ zaraz po tym, jak dostaję pierwszy plik i ustawię jako dopasowany element rez, w następnym cyklu pętli ten nowy element wydaje się nie mieć żadnych elementów podrzędnych.

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

Czy ktoś może mi pomóc z kodu przy użyciu wymienionych modułów node.js?

Odpowiedz

4

Wygląda na to, że robisz dużo więcej pracy, niż potrzebujesz znaleźć pożądany element. Czy możesz opublikować próbną stronę html?

Cheerio zapewnia api wyższego poziomu do znajdowania elementów, których powinieneś użyć.

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

zrobiłem realizować swoje podejście, a ja zatrzymany na uzyskanie, na przykład , trzeci element, gdy część xpath jest jak "../ div [3]/...". Używam kodu wklejonego tutaj http://pastebin.com/pzSYz6Zc Błąd jest również wklejony. – Astro

+0

Bez próby html trudno jest dać sugestie. Proszę pisać przykładową stronę HTML – Noah

+0

nie ma strona html, to część z kodu node.js – Astro

0

Pisałem ten kod, który pobiera prawidłowy element cheerio, podać xpath.

To działa tylko na najbardziej podstawowym XPath, rodzaj, który jest wymieniony w pytaniu i rodzaju, która jest zwykle podawana przez przeglądarki dla elementu.

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

Wygląda jednak na to, że nie jest to implementacja XPath zgodna z W3C. –

0

Tak jest realizacja XPath:

npm install xpath 

Próbka:

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) 

Źródło: https://www.npmjs.org/package/xpath

+1

Niestety parser DOM użyty w przykładzie (xmldom) jest bardzo surowy i nie działa dobrze z prawdziwymi stronami HTML. W tym czasie nie znalazłem jeszcze parsera zgodnego z DOM zgodnego z xpath. –