【问题标题】:Puppeteer page.click doesn't work in headless modePuppeteer page.click 在无头模式下不起作用
【发布时间】:2020-03-28 19:35:44
【问题描述】:

有什么问题

我尝试使用 Puppeteer 单击某个元素,并在此任务上尝试了 page.clickpage.evaluate

  • 如果在headless=false 模式下,两种方法都可以正常工作。
  • 如果在headless=true 模式下,page.evaluate 有效,但page.click 永远挂起

我当时所做的是,page.waitForSelector 显式用于page.click 之前的元素,请参见下面的代码。

看起来waitForSelector 也永远挂起。

谁能帮我理解为什么它在无头模式下挂起?

环境

chrome version is HeadlessChrome/80.0.3987.0
puppeteer version 2.1
macOS catalina 10.15.3

代码


const pptr = require('puppeteer');

console.log(pptr.version);

(async () => {
    var br = await pptr.launch({
        headless: true,
        defaultViewport: null,
        args: [
            '--user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36',
            '--user-data-dir=/tmp/user_data/',
        ],
    });
    var page = await br.newPage();
    var url = 'https://www.lookfantastic.com/brands/aesop/view-all.list';
    var css = 'div.responsiveProductListPage_topPagination button[aria-label="next page" i]:not([disabled])';

    const chrome_version = await page.browser().version();
    console.log(`chrome version is ${chrome_version}`);

    await page.goto(url);
    await page.waitForSelector(css, { visible: true });  // when headless=true, hangs here.

    await Promise.all([
        page.click(css),
        //page.evaluate((css) => { document.querySelector(css).click(); }, css),
        page.waitForNavigation({waitUntil: 'networkidle0'}),
    ]);
    console.log('success');
    await new Promise(r => setTimeout(r, 1000));
    await br.close();
})();

【问题讨论】:

  • 你试过在无头模式下截图吗?
  • @Capripot,很好的建议,现在让我试试,一会就回来。
  • @Capripot,我尝试设置较大的视口大小,现在page.click 工作了,非常感谢 :-)

标签: node.js puppeteer


【解决方案1】:

根据您的评论,无头屏幕的大小可能不适合您正在测试的元素。此元素是否应该显示在笔记本电脑大小的屏幕上(在您的情况下宽度 > 1200 像素)?

您可以通过--window-size=width,height选项设置Puppeteer的窗口大小,例如:

args: [
            '--user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36',
            '--user-data-dir=/tmp/user_data/',
            '--window-size=1200,800',
        ],

【讨论】:

  • 感谢您发布答案,您能解释一下为什么page.evaluate 在设置窗口大小之前会起作用吗?
  • 我的意思是,page.evaluate 可能没有点击正确的东西,但它没有挂起。
  • 可能是querySelector没有考虑元素的可见性,只定位元素,然后点击假定的位置。
  • '--start-maximized' 可能也有帮助。
  • @AlferdNobel --start-maximized 在无头模式下可能无法正常工作
【解决方案2】:

我发现防止此问题的更正确方法是在单击之前调用悬停,如下所示:

await page.hover(selector)
await page.click(selector)

这样,浏览器将滚动到选择器,确保它可见并且可以被点击,而不管窗口大小。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-12-09
    • 2021-06-13
    • 1970-01-01
    • 1970-01-01
    • 2018-04-03
    • 2019-09-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多