Node JS Puppteer Бесконечный цикл прокрутки - PullRequest
0 голосов
/ 05 октября 2018

Я изучаю Puppeteer и пытаюсь почистить сайт, в котором реализована бесконечная прокрутка.Я могу получить все цены из списка, прокручивая вниз с задержкой в ​​1 секунду. Вот URL-адрес

Что я хочу сделать, это открыть элемент из списка, получить название продукта, вернуться к списку, выбрать второй продукт и сделать это для всехпродукты.

const fs = require('fs');
const puppeteer = require('puppeteer');
function extractItems() {
  const extractedElements = document.querySelectorAll('.price');
  const items = [];
  for (let element of extractedElements) {
    items.push(element.innerText);
  }
  return items;
}
async function scrapeInfiniteScrollItems(
  page,
  extractItems,
  itemTargetCount,
  scrollDelay = 1000,
) {
  let items = [];
  try {
    let previousHeight;
    while (items.length < itemTargetCount) {
      items = await page.evaluate(extractItems);
      previousHeight = await page.evaluate('document.body.scrollHeight');
      await page.evaluate('window.scrollTo(0, document.body.scrollHeight)');
      await page.waitForFunction(`document.body.scrollHeight > ${previousHeight}`);
      await page.waitFor(scrollDelay);
    }
  } catch(e) { }
  return items;
}
(async () => {
  // Set up browser and page.
  const browser = await puppeteer.launch({
    headless: false,
    args: ['--no-sandbox', '--disable-setuid-sandbox'],
  });
  const page = await browser.newPage();
  page.setViewport({ width: 1280, height: 926 });
  // Navigate to the demo page.
  await page.goto('https://www.clubfactory.com/views/product.html?categoryId=53&subId=53&filter=%7B%22Price%22%3A%5B%7B%22beg%22%3A1.32%2C%22end%22%3A0%7D%5D%7D');
  // Scroll and extract items from the page.
  const items = await scrapeInfiniteScrollItems(page, extractItems, 4000);
  // Save extracted items to a file.
  fs.writeFileSync('./prices3.txt', items.join('\n') + '\n');
  // Close the browser.
  await browser.close();
})(); 

Любая помощь приветствуется

1 Ответ

0 голосов
/ 05 октября 2018

РЕДАКТИРОВАТЬ: я добавил рабочий фрагмент для конкретного веб-сайта, указанного в вопросе.

Если вы занимаетесь очисткой, иногда вы должны разбить пользовательский опыт на несколько кусочков, чтобы имитироватьреальный пользователь, чтобы получить те фактические данные, которые он получит.

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

Но вы также можете думать по-другому,

  1. получить первый элемент,
  2. нажмите, чтобы открыть в новой вкладке,
  3. парсинг данных,
  4. закрыть вкладку,
  5. удалить элемент,
  6. и перейти к следующему элементу.Прокрутите и дождитесь появления нового элемента.

Проблема с концепцией заключается в том, что вы никогда не узнаете, как запускаются прокрутка и нажатие.Для прокрутки на разных сайтах может быть несколько событий.И предоставленный сайт находится в vueJS.

Фрагмент кода

Селектор для каждого продукта: #__layout > section > main > section > section > div.products > div > div.

Мы прокрутим селектор, разберемся с ним, а затем удалим его.После этого мы запустим событие прокрутки, чтобы браузер узнал, что что-то изменилось.

window.scrollTo(0, 0);
const selector = `#__layout > section > main > section > section > div.products > div > div`;
const element = document.querySelector(selector)
element.scrollIntoView()
element.remove()

Результат: (анимация gif)

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

Это работает и на таких сайтах, как producthunt. Video Link для лучшего качества просмотра.

const delay = d=>new Promise(r=>setTimeout(r,d))

const scrollAndRemove = async () => {
    // scroll to top to trigger the scroll events
    window.scrollTo(0, 0);
    const selector = `.title_9ddaf`;
    const element = document.querySelector(selector);

    // stop if there are no elements left
    if(element){
      element.scrollIntoView();

      // do my action
      // wait for a moment to reduce load or lazy loading image
      await delay(1000);
      console.log(element.innerText);
      // end of my action

      // remove the element to trigger some scroll event somewhere
      element.remove();

      // return another promise
      return scrollAndRemove()
    }
}

scrollAndRemove();

...