Не понятное поведение парсера на 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 шт):

Автор решения: vsemozhebuty

А разве вот здесь вы не присваиваете всем книгам каждый раз текущую цену, всё время её перезаписывая для всех элементов?

    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);
  }
})();
→ Ссылка