Кукольник - тестирование разных селекторов для страницы - PullRequest
1 голос
/ 21 апреля 2020

Я пытаюсь, чтобы мой сценарий кукловода перебирал селекторы.

Причина в том, что - в зависимости от того, что я запрашиваю через мой скрипт, я могу получить немного разные элементы на странице.

По сути, у меня есть метод page.evaluate, который выполняет очистку следующим образом

    while (currentPage <= pagesToScrape) {

        let newProducts = await page.evaluate(({identified}) => {
          let results = [];

          let items = document.querySelectorAll(
            identified
          );
console.log(items)


          items.forEach((item) => {
            var prod, price;
            if (identified == selectors[0]) {
              prod = item.querySelector("div>div>div>div>div>a>h3").innerText;
              price = item.querySelector("div>div>div>div>div>div>span>span")
                .innerText;
            } else {
              prod = item.querySelector("div>a>h4").innerText;
              price = item.querySelector("div>div>div>div>span>span").innerText;
            }
            results.push({
              Product: prod !== "" ? prod : "",
              Price: price !== "" ? price : "",
            });
          });
          console.log("results");
          console.log(results.length);
          return results;
        });
        product_GSH = product_GSH.concat(newProducts);
        if (currentPage < pagesToScrape) {
          console.log(identified)
          await Promise.all([
            await page.click(buttonSelector),
            await page.waitForSelector(identified),
          ]);
        }

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

const selectors = ['div[class = "sh-dlr__list-result"',"div[class = 'sh-dgr__content'"]
  //works
  const chooseSelector = await page.waitForFunction((selectors) => {
    for (const selector of selectors) {
      if (document.querySelector(selector) !== null) {
        return selector;
      }
    }
    return false;
  }, {}, selectors);

  const identified = await chooseSelector.jsonValue();

console.log (идентифицировано)

Проблема, с которой я столкнулся, заключается в том, что в рамках page.evaluate я могу легко запустить идентификатор и найти правильный для использования. Но мне нужно снова проанализировать его в конце запроса, чтобы очистить следующую страницу. Когда я пытаюсь переназначить имя переменной на правильный идентификатор внутри page.evaluate, он не анализирует его.

Когда я запускаю это, код запускается, но я не могу изменить селектор внутри Обещание внизу с page.waitfor (поэтому он работает с некоторыми страницами, но когда это не та страница, я не могу чередовать выбранный селектор). это полный код.

        product_GSH = product_GSH.concat(newProducts);
        if (currentPage < pagesToScrape) {
          await Promise.all([
            await page.click(buttonSelector),

            page.waitForNavigation()
          ]);
        }
        currentPage++;
      }
      browser.close();

      return res.send(product_GSH);
    } catch (e) {
      return res.send(e);
    }
  });
});

Я думаю, что один из способов решить эту проблему - посмотреть на функцию promise.all и заменить ее чем-то немного другим.

Спасибо за помощь в решении этой проблемы!

Последний вопрос, если вы можете помочь - Как я могу убедиться, что при выборе, скажем, 5 страниц, а результатов только 3, отправляет 3 страницы. Я обнаружил, что если я скажу, что есть больше страниц, он не отправляет никакого ответа.

В идеале, я пытаюсь, чтобы этот код мог перебирать различные селекторы. Я пробовал кучу разных методов, и ошибки CORS и многое другое, очень потерянный. Было бы неплохо также получить какую-то определенную ошибку от кукловода!

Оцените помощь:)

Ответы [ 2 ]

3 голосов
/ 23 апреля 2020

Вы должны использовать page.waitForNavigation вместе с page.click(buttonSelector) обещаниями. Кроме того, чтобы использовать Promise.all, вы должны передать ему фактические обещания и невыполненные обещания , как вы делаете:

if (currentPage < pagesToScrape) {
  await Promise.all([
    page.click(buttonSelector),
    page.waitForNavigation()
  ]);
}

Вы можете упростить селекторы Например,

div[class = "sh-dlr__list-result"

может быть

div.sh-dlr__list-result

Селектор

const buttonSelector = "a[id='pnnext']>span[style='display:block;margin-left:53px']";

неправильный; Вы никогда не должны полагаться на стиль для запроса селектора; это может быть легко изменено c; вместо этого вы можете определить его следующим образом:

const buttonSelector = "a#pnnext";

После внесения этих изменений мы получим надлежащие результаты, например, он выдаст:

product_GSH.length 100
product_GSH [...]

ОБНОВЛЕНИЕ

Если вы хотите обрабатывать результаты с количеством страниц, меньшим pagesToScrape, вам нужно поискать buttonSelector, прежде чем выполнить щелчок по нему следующим образом:

if (currentPage < pagesToScrape && await page.$(buttonSelector) !== null) {
  await Promise.all([
    page.click(buttonSelector),
    page.waitForNavigation()
  ]);
}
2 голосов
/ 23 апреля 2020

Promise.all выглядит как место, чтобы решить эту проблему. Я не лучший с функциями обещания, хотя

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...