Получить все ссылки с XPath в Puppeteer (приостановка или не работает)? - PullRequest
0 голосов
/ 30 ноября 2018

Мне необходимо использовать XPath для выбора всех ссылок на странице, чтобы затем мое приложение Puppeteer могло перейти по ним и выполнить некоторые действия.Я обнаружил, что метод (код ниже) иногда зависает, и мой сканер будет приостановлен.Есть ли лучший / другой способ получения всех ссылок из XPath?Или в моем коде есть что-то неправильное и может приостановить работу моего приложения?

try {
  links = await this.getLinksFromXPathSelector(state);
} catch (e) {
  console.log("error getting links");
  return {...state, error: e};
}

Что вызывает:

async getLinksFromXPathSelector(state) {
 const newPage = state.page
 // console.log('links selector');
 const links = await newPage.evaluate((mySelector) => {
   let results = [];
   let query = document.evaluate(mySelector,
     document,
     null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
   for (let i=0, length=query.snapshotLength; i<length; ++i) {
     results.push(query.snapshotItem(i).href);
   }
   return results;
 }, state.linksSelector);
  return links;
}

XPath находится в state.linksSelector.

1 Ответ

0 голосов
/ 01 декабря 2018

Вы можете использовать page.$x(), чтобы оценить выражение XPath и получить массив ElementHandle.Может быть целесообразно использовать page.waitForXPath() заранее, чтобы гарантировать, что элементы, указанные в строке XPath, добавляются в DOM.

Затем вы можете передать ElementHandle массив элементов в контекст страницы через page.evaluate() и возвращает массив, содержащий значения атрибута href для каждого элемента.

const xpath_expression = '//a[@href]';
await page.waitForXPath(xpath_expression);
const links = await page.$x(xpath_expression);
const link_urls = await page.evaluate((...links) => {
  return links.map(e => e.href);
}, ...links);

console.log(link_urls);
...