Не понятное поведение парсера на node js
Пишу небольшой парсер(web-scraping) на node js и столкнулся с проблемой . Я парсю сайт на котором есть книги . с помощью puppetter забираю html , а с помощью Cheerio остовляю только текст элементов с классом .book__title . Всё работает нормально . Я сделал аналогично для класса .book__price , но вместо того чтобы выдавать каждому элементу уникальную цену - скрапер выдаёт одну и туже цену для всех элементов . Не знаю что делать .
const puppeteer = require('puppeteer');
const cheerio = require('cheerio');
async function main(URL) {
const browser = await puppeteer.launch({
headless: true,
});
const page = await browser.newPage();
await page.goto(URL);
/**
* Получим содержимое страницы в виде HTML-кода.
*/
const content = await page.content();
/**
* Загрузим код в cheerio.
*/
const $ = cheerio.load(content);
/**
* Создадим массив для хранения заголовков статей.
*/
const books = [];
/**
* Метод slice() используется для доступа только к элементам
* в определённом диапазоне.
* Перебираем их с помощью метода each().
*/
$('.book__title').slice(4, 20).each((idx, elem) => {
/**
* Получаем внутренний HTML-код, соответствующий тексту заголовка.
*/
let title = $(elem).text();
/**
* Помещаем заголовок в массив.
*/
books.push({title});
})
// Тоже самое что и выше но с изминениями
$('.book__price').slice(4, 20).each((idx, elem) => {
let price = $(elem).text()
var val
// Убираем \n
price = price.substring(price.indexOf("\n") + 1);
// Убираем пробелы
price = price.split(" ").join("")
// перебираем масив и добовляем в объекты значение price
for(val of books){
val.price = price
}
})
browser.close();
/**
* Выводим массив заголовков в консоль.
*/
console.log(books);
}
main("URL");
По идее должно выдаваться {title: Имя книги price: цена} Выдаёт {title: Имя книги price: 119(это фиксированная цена)} Вот url сайта: https://librarius.md/ru/search?search=%D0%B2%D0%B5%D0%B4%D1%8C%D0%BC%D0%B0%D0%BA
Ответы (1 шт):
А разве вот здесь вы не присваиваете всем книгам каждый раз текущую цену, всё время её перезаписывая для всех элементов?
for(val of books){
val.price = price
}
Что если заменить это на:
books[idx].price = price
P.S. Без cheerio:
const puppeteer = require('puppeteer');
(async function main() {
try {
const browser = await puppeteer.launch();
const [page] = await browser.pages();
await page.goto('https://librarius.md/ru/search?search=%D0%B2%D0%B5%D0%B4%D1%8C%D0%BC%D0%B0%D0%BA');
const data = await page.evaluate(() =>
[...document.querySelectorAll('.book')]
.slice(4, 20)
.map(book => ({
title: book.querySelector('.book__title').innerText,
price: book.querySelector('.book__price').innerText.replace(/\s/g, ''),
}))
);
console.log(data);
await browser.close();
} catch (err) {
console.error(err);
}
})();