【问题标题】:How Do I Retrieve New Page Content in an SPA using Puppeteer?如何使用 Puppeteer 在 SPA 中检索新页面内容?
【发布时间】:2020-11-01 22:16:12
【问题描述】:

我正在尝试抓取的页面加载了初始内容主体,然后是页面底部的“加载更多”按钮。单击“加载更多”按钮时,该按钮将从页面中删除,页面会在页面下方加载其他内容(保留初始加载的内容),并且新的“加载更多”按钮放置在底部页。当点击“加载更多”按钮时,页面的 URL不会改变。 IE。它的行为类似于单页应用程序 (SPA)。

使用 Puppeteer 我可以导航到页面:

let page = await browser.newPage();
  await page.goto('https://www.someURL.com/home', {
    waitUntil: 'domcontentloaded',
  });

然后我使用page.$$eval() 找到“加载更多”按钮并单击它。该页面加载附加内容以及底部的新“加载更多”按钮。但是,我找不到使用 Puppeteer 来“刷新”我的 page 变量的方法,以便我可以再次调用 page.eval$$() 以找到新的“加载更多”按钮。调用page.reload() 会将页面恢复到我调用page.goto() 时的状态。

我搜索了 Puppeteer 文档并查看了数十个示例,但找不到执行此操作的方法。鉴于 SPA 的盛行,我必须忽略一些显而易见的事情。

这可能吗?

编辑:使用@vsemozhetbyt 建议的附加代码:

 let theButton = await page.$('button.sc-fzoiQi');
  do {
    await page.evaluate(theButton => {
      theButton.click();
    }, theButton);
  } while ((await buttonExists(page)) !== null);
};
async function buttonExists(page) {
  return await page.$('button.sc-fzoiQi');
}

使用上面的方法,第一次点击按钮,但是while 表达式永远不会被评估。 IE。其中的语句 - return await page.$('button.sc-fzoiQi') 永远不会返回。

【问题讨论】:

  • 尝试将此行放在do 子句中:let theButton = await page.$('button.sc-fzoiQi');。该按钮可以在每次更新时删除并重新创建,因此我们需要在每次迭代时重新引用该元素。
  • 做到了。奇怪的是,它需要我放慢 browser 实例(将 sloMo: 1000 传递到 puppeteer.launch() 以使点击生效,但我可以忍受它。谢谢!
  • 您也可以尝试使用 delay 选项在 puppeteer 上下文中单击,以检查这是否有帮助。也许这将是一个更轻的缺点。 github.com/puppeteer/puppeteer/blob/main/docs/…

标签: javascript puppeteer


【解决方案1】:

你可以试试这样的

do {
  // Get the button, click, wait for the data, get the data.
} while (await page.$(buttonSelector) !== null);

【讨论】:

  • 不幸的是,“加载更多”按钮是页面上众多按钮元素之一,选择它的唯一方法是通过page.$$eval() 选择所有按钮,然后检查返回数组中的每个元素使用forEachelement.textContent === "Load more"
  • 您可以将此逻辑提取到异步函数中并在while 子句中调用它。或者您可以使用 while 循环和 break
  • 所以,我找到了一种使用page.$() 选择按钮的方法,无论它在页面上出现多少次。我已经使用您的建议使用附加代码更新了我的问题,但是在while 中对page.$() 的调用永远不会返回。想法?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-10
  • 2021-04-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多