2017-01-25 2 views
1

Я пишу веб-скребок с узлом и рассматриваю использование модуля, такого как Cheerio или JSDom, для анализа HTML в DOM для набора URL-адресов. Однако у меня есть определенная функциональность, которая необходима.Как я могу получить селектор CSS для элемента по значению в NodeJS?

Моя цель - создать скребок, который может очистить несколько похожих страниц на сайте за несколько ключевых частей информации. Однако у меня есть некоторые примеры данных, которые содержат эти части информации, и я хочу использовать их для динамической сборки модели для этих страниц, а затем очистить остальную часть сайта с помощью этой модели.

Чтобы уточнить, если есть три страницы на сайте, каждый из которых содержит различные продукты:

Страница 1:

<html> 
<body> 
<h1>Product 1</h1> 
<p>Desc</p> 
<small>$2.05</small> 
</body> 
</html> 

Страница 2:

<html> 
<body> 
<h1>Product 2</h1> 
<p>Desc</p> 
<small>$8.05</small> 
</body> 
</html> 

Страница 3:

<html> 
<body> 
<h1>Product 3</h1> 
<p>Desc</p> 
<small>$5.07</small> 
</body> 
</html> 

Sa y У меня уже есть данные для первого продукта (я знаю название продукта, описание и цену). Я хочу получить селектора каждого из этих элементов с помощью первой страницы, а затем использовать эти селекторы для очистки данных с других страниц.

С учетом содержимого тега в DOM, как я могу получить CSS-селектор для этого элемента? Например:

<html> 
    <body> 
    <h1>Hello world</h1> 
    </body> 
</html> 

Как я могу обеспечить Cheerio/JSDom со строкой, как «Привет мир» и он возвращает CSS селектор в DOM, где элемент проживает?

Есть ли простой способ сделать это (в том числе с использованием другого фреймворка), или это единственный способ просто пропустить весь объект DOM и проверить значения каждого элемента отдельно?

+0

Будет множество разных XPaths, которые возвращают тот же нодлист. Какой вы хотите? Я предполагаю, что '// * [text() = 'Hello world']' не то, что вам нужно? – OrangeDog

+0

Что вы хотите узнать? Поскольку вы могли бы иметь XPath так же просто, как '// * [. = "Hello world"] ' – skAstro

+0

Все, что я хочу, это найти элемент/путь, где элемент, содержащий« мир привет », поэтому я могу использовать этот путь для извлечения другой информации позже. В принципе, я автоматически создаю свою модель скребков с использованием данных семян. –

ответ

0

Это самый простой и эффективный способ выполнить с помощью модели SAX, но вместо этого можно применить к обходу DOM.

var match, path = []; 

parser.on('start', function(tag) { currentPath.push(tag); }); 
parser.on('end', function(tag) { currentPath.pop(); }); 

parser.on('text', function(text) { 
    if (!match && text === 'Hello world') { 
    match = path.join('/'); 
    } 
}); 

Если вам нужно построить DOM в любом случае, вы можете использовать XPath, чтобы найти узел (который внутри только петли весь DOM), то цикл до родителей.

var path = []; 
var node = document.xpath('//*[.="Hello world"]')[0]; 

do { 
    path.push(node.tag); 
} while (node = node.parent); 

var match = path.reverse().join('/'); 

Этот второй метод намного более неэффективен, особенно если у вас есть много разных узлов для поиска. Метод SAX может охватывать все из них за один проход, но может работать с искаженным вводом в зависимости от реализации парсера.

Для селекторов CSS замените '/' на ' > '.

+0

В вашем первом предложении, что такое объект парсера? Не могли бы вы предоставить более полный обзор того, что делает ваш код? –

+0

Это SAX-парсер. Предположительно, какой-то «поток» вы можете передать ответ или «EventEmitter», который вы можете дать DOM для запуска. – OrangeDog

+0

Я только что исправил свой вопрос, чтобы спросить о CSS-селекторах. Используется ли ваше решение SAX? –

Смежные вопросы