操纵up的page.click有效,但page.evaluate +文档单击无效

时间:2020-03-24 08:49:40

标签: javascript puppeteer

我看过很多帖子(例如,参见herehere),说我可以通过以下代码单击某些内容,

await page.click('.route-redirect-box');   // via Puppeteer page.click

await page.evaluate((css_selector) => {
  document.querySelector(css_selector).click();  // or via page.evaluate
}, css);

但是,正如我在某些网站上测试的那样,使用page.click模式似乎page.evaluate始终可以工作,但是headless: false却不能工作。

例如,在此website页上,我尝试单击以下内容,

var css = '#searchPaginationTop > nav > a:nth-child(5)';
await page.evaluate((css_selector) => { document.querySelector(css_selector).click();}, css);

什么都没有发生,但是如果我使用page.click,它会按预期工作。

我在想,我要单击的元素不是普通的 clickable 元素,因为该元素的html代码如下,

<a class="svg" data-goto-page="3" data-total-pages="3" data-ga="event" data-ga-category="Brands at allbeauty-Burberry-Pagination" data-ga-action="Brands at allbeauty-Burberry-Pagination-Next-Touch" data-ga-label="Brands at allbeauty-Burberry-Pagination-Next-Link">
    <svg viewBox="0 0 21.9 38.7" alt="Next Page" title="Next Page ">
        <use xlink:href="#icon-ab-arrow-right">
        </use>
    </svg>
</a>

可能是因为此元素是data-ga东西,所以page.evaluate无法单击它吗?

2 个答案:

答案 0 :(得分:4)

据我所知,内容似乎是动态注入的。 这意味着,通过使用Puppeteer的waitForSelector,您可以等待它发生,然后再继续。应该遵循这些原则(我自己不能复制它,因为我不知道如何触发导航更新):

await page.click('.route-redirect-box');
const css = '#searchPaginationTop > nav > a:nth-child(5)';
await page.waitForSelector(css);
await page.evaluate((css_selector) => { document.querySelector(css_selector).click();}, css);

答案 1 :(得分:3)

简短回答

  • page.evaluate(() => document.querySelector('SELECTOR').click());仅触发click事件
  • page.click('SELECTOR')试图模仿点击时的人类行为

说明

让我们查看两种方法的文档以真正了解正在发生的事情。

page.evaluate(() => document.querySelector('SELECTOR').click());

让我们看看MDN documentation怎么说:

[...]触发元素的click事件。

仅此而已。它 just 触发click事件,以便所有监听该元素的click事件的处理程序都被调用。这意味着,它并不关心元素是否在当前视口之外。该元素甚至可能被隐藏(通过CSS),并且click事件仍然会触发。

让我们将其与“伪装方式”进行比较:

page.click

puppeteer documentation中与page.click有关的部分:

此方法使用selector获取一个元素,如果需要,将其滚动到视图中,然后使用page.mouse单击该元素的中心。 [...]

这意味着,操纵p的人在这里模仿人类的行为。首先,将元素滚动到视图中,然后将鼠标移到元素顶部(触发诸如mouseovermouseenter等其他事件)。最后,通过模拟鼠标单击该按钮(请参见伪造者代码中的相应Mouse类)。这也会触发任何相关事件(例如mousedown)。

当您自己触发JavaScript事件时,复杂的UI库可能不喜欢它。请记住,它们通常针对人机互动而非针对与机器人的互动进行了优化。这意味着,UI库可能会监听mousedownmouseenter事件(例如),而不是直接监听click事件。

表现出“类人”

与未知网站互动时,最好尝试表现得尽可能人性化。即使页面没有任何特定的“反机器人”措施,也可能会使用预期特定事件流的框架。

顺便说一句,您不是唯一遇到此问题的人。看看这些问题是否有类似问题: