简体   繁体   English

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

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

I've seen so many posts (for example, see here and here ), saying that I could click on something via the following code,我看过很多帖子(例如,请参阅此处此处),说我可以通过以下代码单击某些内容,

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);

However, as I tested on some websites, looks like page.click always works, but page.evaluate doesn't, using headless: false mode.然而,正如我在一些网站上测试的那样,看起来page.click总是有效,但page.evaluate没有,使用headless: false模式。

For example, this website page, I tried to click on something as follows,比如这个网站页面,我尝试点击如下内容,

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

nothing happened at all, but if I use page.click , it worked as expected.什么也没发生,但如果我使用page.click ,它会按预期工作。

I'm thinking that, the element I wanted to click is not a normal clickable element, since the html code for that element is as follows,我在想,我想点击的元素不是普通的可点击元素,因为该元素的 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>

Could it be because this element is some data-ga stuff, so page.evaluate cannot click on it?是不是因为这个元素是一些data-ga东西,所以page.evaluate不能点击它?

Short answer简答

  • page.evaluate(() => document.querySelector('SELECTOR').click()); just fires the click event只是触发click事件
  • page.click('SELECTOR') tries to mimic human behavior when clicking page.click('SELECTOR')尝试在点击时模仿人类行为

Explanation解释

Let's check the documentation for both methods to really understand what is happening.让我们查看这两种方法的文档以真正了解发生了什么。

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

Let's see what the MDN documentation says:让我们看看MDN 文档是怎么说的:

[...] It fires the element's click event. [...] 它触发元素的点击事件。

That's all it does.这就是它所做的一切。 It just fires the click event, so that all handlers listening to that click event of the element are called.只是触发click事件,因此所有侦听该元素的 click 事件的处理程序都会被调用。 This means, it does not care if the element is outside of the current viewport.这意味着,它不关心元素是否在当前视口之外。 The element might even be hidden (via CSS) and the click event would still fire.该元素甚至可能被隐藏(通过 CSS)并且click事件仍然会触发。

Let's compare that to the "puppeteer-way":让我们将其与“傀儡方式”进行比较:

page.click

The part of the puppeteer documentation regarding page.click : page.click 文档中关于page.click

This method fetches an element with selector , scrolls it into view if needed, and then uses page.mouse to click in the center of the element.此方法使用selector获取元素,如果需要将其滚动到视图中,然后使用page.mouse单击元素的中心。 [...] [...]

That means, that puppeteer mimics human behavior here.这意味着,木偶操纵者在这里模仿人类行为。 First, the element is scrolled into view, then the mouse is moved on top of the element (triggering any other events like mouseover , mouseenter , etc. on the way).首先,元素滚动到视图中,然后鼠标移动到元素顶部(在途中触发任何其他事件,如mouseovermouseenter等)。 Finally, the button is clicked by simulation a mouse (see the corresponding Mouse class in the puppeteer code).最后通过模拟鼠标点击按钮(见puppeteer代码中对应的Mouse类)。 This also triggers any related events (like mousedown ).这也会触发任何相关事件(如mousedown )。

Complex UI libraries might not like it, when you trigger JavaScript events on your own.当您自己触发 JavaScript 事件时,复杂的 UI 库可能不喜欢它。 Keep in mind, they are often optimized for human interaction, not for interaction with bots.请记住,它们通常针对人类交互进行优化,而不是针对与机器人的交互进行优化。 That means, the UI library might listen to the mousedown or mouseenter event (as an example) instead of directly listening to the click event.这意味着,UI 库可能会侦听mousedownmouseenter事件(例如),而不是直接侦听click事件。

Behaving "human-like"表现得“像人”

When interacting with an unknown website, it is best to try to behave as human as possible.在与未知网站互动时,最好尽量表现得像人一样。 Even pages that do not have any specific "anti-bot" measures, might use frameworks that expect a specific flow of events.即使页面没有任何特定的“反机器人”措施,也可能使用期望特定事件流的框架。

By the way, you are not the only one having this problem.顺便说一下,您不是唯一遇到此问题的人。 Check out these questions for similar problems:查看这些问题是否有类似问题:

From what I can tell, the content seem to be injected dynamically.据我所知,内容似乎是动态注入的。 That means, by using waitForSelector of Puppeteer, you can wait for it to happen before continuing.这意味着,通过使用 Puppeteer 的waitForSelector ,您可以在继续之前等待它发生。 Something along these lines should do (can't replicate it myself, since I don't know know how to trigger the update of the nav):应该按照这些方式做一些事情(不能自己复制,因为我不知道如何触发导航更新):

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