2013-04-15 15 views
5

Öğeyi xpath ile alacak olan node.js'de bir işlev yazmaya çalışmak.Xpath ve cheerio kullanarak öğe alma

Ben

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

Benim DOM cheerio yüklenir gibi istenilen dom elemanının bir xpath sahip aracılığıyla fs modülü (Bu web sayfası yerel olarak saklanan çünkü):

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

Sonra Her bir xpath parçası üzerinden yinelemeye çalışıyorum, dom ağacının elementini alıyorum, isim ve eleman numarası eşleşiyorsa bu çocukları kontrol edin ve eğer yaparsa, rez bu matematiksel elemen olarak saklayın t. Sonra yeni xpath parçası ile kazmaya devam ediyorum. Kod böyle görünüyor, ama istediğimi elde edemiyorum çünkü ilk makineyi aldıktan sonra ve rez'u eşleşen eleman olarak ayarladıktan sonra, döngü döngüsü için bir sonraki döngüde bu yeni öğe herhangi bir alt öğe içermiyor gibi görünüyor.

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

Belirtilen node.js modüllerini kullanarak herhangi bir kimse bana kodda yardımcı olabilir mi?

cevap

4

Daha çok iş yapıyormuşsunuz gibi görünüyor, o zaman istenen öğeyi bulmanız gerekiyor. Örnek bir html sayfası gönderir misiniz?

Cheerio, kullanmanız gereken öğeleri bulmak için daha yüksek düzeyde bir API sağlar.

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

, üçüncü element, xpath'ın bir kısmı '../ div [3]/...' gibi olduğunda. Burada yapıştırılan kodu kullanıyorum http://pastebin.com/pzSYz6Zc Hata da yapıştırıldı. – Astro

+0

Herhangi bir örnek html olmadan size öneri vermek zordur. Lütfen bir html sayfası gönderin – Noah

+0

no html sayfası yok, node.js kodunun bir parçası – Astro

0

Bir xpath verilen cheerio doğru elemanı alır bu kodu, yazdım.

Bu, yalnızca en temel xpath için, soruda belirtilen türden ve genellikle bir öğe için tarayıcılar tarafından verilen türden çalışır.

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

Yine de W3C uyumlu bir XPath uygulaması gibi görünmüyor. –

0

Evet xpath uygulaması vardır:

npm install xpath 

Örnek:

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) 

Kaynak: Ben senin yaklaşımını uygulamak vermedi ve ben örneğin alma konusunda takılıp https://www.npmjs.org/package/xpath

+1

Maalesef, örnekte (xmldom) kullanılan DOM ayrıştırıcısı çok sıkıdır ve gerçek HTML sayfalarıyla iyi çalışmaz. Henüz xpath ile uyumlu affedici bir DOM ayrıştırıcısı bulamadım. –