2013-04-15 4 views
5

xpath로 요소를 가져올 node.js 함수를 작성하려고합니다.xpath 및 cheerio를 사용하여 요소 가져 오기

제가

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

내 DOM은 안녕에로드와 같은 원하는 DOM 요소의 XPath를 가지고 통해 FS 모듈 (I이 웹 페이지는 로컬로 저장되어 있기 때문에)

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

을이어서 각 xpath 부분을 반복하고 dom 트리의 요소를 가져오고 이름과 요소 번호가 일치하면 자식을 확인한 다음 rez을 mathed elemen으로 저장하려고합니다. 티. 그렇다면 새로운 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

, 세 번째 요소, xpath의 일부가 '../ div [3]/...'과 같은 경우. 여기에 붙여 넣은 코드를 사용합니다. http://pastebin.com/pzSYz6Zc 오류도 붙여 넣습니다. – Astro

+0

샘플 HTML이 없으면 제안을하기가 어렵습니다. 예제 HTML 페이지를 게시하십시오 – Noah

+0

html 페이지가 없습니다. node.js 코드의 일부입니다. – Astro

0

나는 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 파서를 찾지 못했습니다. –