waitForNavigation挂起,即使页面已加载

bsa*_*sam 3 puppeteer

我正在尝试使用puppeteer自动登录网站,使用以下脚本:

const puppeteer = require('puppeteer');
async function logIn(userName, password) {
    const browser = await puppeteer.launch();
    const page = await browser.newPage();
    await page.goto('https://foo.com'); //anonymized host
    await page.type('[name="Email"]', userName);
    await page.type('[name="Pass"]', password);
    page.click('[type=submit]');
    await page.waitForNavigation({waitUntil: 'load'});
}

logIn('user@domain.com')
Run Code Online (Sandbox Code Playgroud)

awaitwaitForNavigation最终超时为30秒.使用{headless: false}相同的脚本启动木偶操作,我可以检查铬的devtools,document.readyState在超时的thresold间隔之前逐渐"完成".难道我做错了什么?

Eve*_*tss 14

根据Puppeteer文档,点击提交和等待导航的正确模式是这样的:

await Promise.all([
  page.waitForNavigation({ waitUntil: 'load' }),
  page.click('[type=submit]'),
]);
Run Code Online (Sandbox Code Playgroud)

  • 对我来说,这不会解决任何问题,初始情况与上面的示例非常相似。 (2认同)

小智 7

除了 Everettss 的答案之外,我想提供一个更现代的代码。基本上,动机不是执行任何操作和调用waitFornavigation,而是反其道而行之。像这样的东西:

//Get the promise which isn't resolved yet
const navigationPromise = page.waitForNavigation(); 

//Perform the activity (Click, Goto etc). Note that the link is any valid url
await page.goto(link);

//wait until the navigationPromise resolves
await navigationPromise;
Run Code Online (Sandbox Code Playgroud)

根据讨论,这有助于避免竞争条件

此代码使用 async/await,它比基于 Promise 的代码更具可读性