我看过这么多帖子(例如,参见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,它可以按预期工作。

我在想,我要单击的元素不是普通的可点击元素,因为该元素的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无法单击它吗?

最佳答案

简短答案

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

    说明

    让我们查看两种方法的文档以真正了解正在发生的事情。
    page.evaluate(() => document.querySelector('SELECTOR').click());
    让我们看看MDN documentation怎么说:



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

    让我们将其与“伪装方式”进行比较:
    page.click
    puppeteer documentation中有关page.click的部分:



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

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

    表现得像人一样

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

    顺便说一句,您不是唯一遇到此问题的人。查看以下问题以查找类似问题:
  • Click event not triggering in an Angular application
  • Setting value of input field does not work (also Angular)
  • 10-05 20:37
    查看更多