繁体   English   中英

Puppeteer page.click 有效,但 page.evaluate + 文档单击不起作用

[英]Puppeteer page.click works, but page.evaluate + document click doesn't work

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

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模式。

比如这个网站页面,我尝试点击如下内容,

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 文档是怎么说的:

[...] 它触发元素的点击事件。

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

让我们将其与“傀儡方式”进行比较:

page.click

page.click 文档中关于page.click

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

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

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

表现得“像人”

在与未知网站互动时,最好尽量表现得像人一样。 即使页面没有任何特定的“反机器人”措施,也可能使用期望特定事件流的框架。

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

据我所知,内容似乎是动态注入的。 这意味着,通过使用 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);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM