获取 Puppeteer 中 XPath 的所有链接(暂停或不起作用)?

Can*_*ins 2 javascript xpath node.js google-chrome-devtools puppeteer

我需要使用 XPath 选择页面上的所有链接,然后我的 Puppeteer 应用程序才能单击并执行一些操作。我发现该方法(下面的代码)有时会卡住,我的爬虫会暂停。是否有更好/不同的方式从 XPath 获取所有链接?或者我的代码中是否存在不正确的内容并且可能会暂停我的应用程序的进度?

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

其中调用:

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;
}
Run Code Online (Sandbox Code Playgroud)

XPath 位于state.linksSelector.

Gra*_*ler 6

您可以使用它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);
Run Code Online (Sandbox Code Playgroud)