Получение элемента с помощью xpath и cheerio

Пытаюсь написать в node.js функцию, которая будет получать элемент по xpath.

У меня есть xpath желаемого элемента dom, например

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

Мой DOM загружается в cheerio через модуль fs (потому что эта веб-страница хранится локально):

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

Затем я пытаюсь выполнить итерацию по каждой части xpath, получить элемент дерева dom, проверить его дочерние элементы, совпадают ли имя и номер элемента, и если они совпадают, сохранить rez как этот математический элемент. Затем я продолжаю копаться с новой частью xpath. Код выглядит так, но он не может получить то, что я хочу, потому что сразу после того, как я получаю первый mach и устанавливаю rez в качестве соответствующего элемента, в следующем цикле for этот новый элемент, кажется, не имеет любые дочерние элементы.

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?


person Astro    schedule 15.04.2013    source источник


Ответы (2)


Кажется, что вы делаете гораздо больше работы, чем вам нужно найти нужный элемент. Можете ли вы опубликовать образец 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)
person Noah    schedule 15.04.2013
comment
Я реализовал ваш подход и застрял на получении, например, третьего элемента, когда часть xpath похожа на «../div[3]/...». Я использую код, вставленный здесь pastebin.com/pzSYz6Zc. Ошибка также вставлена. - person Astro; 17.04.2013
comment
Без какого-либо образца html трудно дать вам предложения. Разместите, пожалуйста, пример html-страницы - person Noah; 17.04.2013
comment
под веб-страницей я имею в виду aaa.html, который вы загружаете через var file = fs.readFileSync(aaa.html) - person Noah; 17.04.2013

Да, есть реализация 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

person ton    schedule 03.12.2014
comment
К сожалению, парсер DOM, использованный в примере (xmldom), очень строг и плохо работает с реальными HTML-страницами. В то время я еще не нашел щадящего парсера DOM, совместимого с xpath. - person Emanuele Casadio; 16.10.2015