在puppeteer中使用page.waitForNavigation的正确方法[复制]

问题描述 投票:0回答:1

这个问题在这里已有答案:

我有点困惑page.waitForNavigation我知道它是什么和它做什么但我得到不同的结果基于interenet速度(在这就是我认为是因素)

想象这段代码

    await page.$eval('#username', (el , setting ) => el.value = setting.username , setting );
    await page.$eval('#password', (el , setting ) => el.value = setting.password , setting );
    await page.$eval('form', form => form.submit());
    await page.waitForNavigation();
    await page.goto( 'http://example.com/dashboard'  );

它填写登录表单,提交登录表单,等待提交表单,然后重定向到仪表板

这在我的本地主机上工作正常,我的网速较慢(与服务器相比),但当我上传到服务器时我得到

Error: Navigation Timeout Exceeded: 30000ms exceeded 

如果我从代码中删除await page.waitForNavigation();并且我被重定向到仪表板,它在服务器上工作正常

但现在在localhost我被重定向到仪表板之前可以提交表单...所以我得到you cant see dashboard , your not logged in或类似的东西

我认为决定因素是互联网的速度

在服务器上我有一个非常高的速度,所以表格立即提交,并在await page.waitForNavigation()线之前完成,所以我得到nvigation超时错误

但是在速度较慢的localhost上需要更多的时间来提交,所以我需要在提交表单后有await page.waitForNavigation()否则我会在表单有机会提交之前被重定向到仪表板

所以我正在寻找有更多使用木偶操作经验的人的建议如何处理这种情况...正确的知道我在服务器或localhost上运行时继续编辑我的代码......这很有效但很烦人!

使用后

async function open_tab( setting ){

    const page    = await global_browser.newPage();
    await page.setViewport({ width: 1000, height: 768});


    return await new Promise(async (resolve, reject ) => {

        await page.$eval('#username', (el , setting ) => el.value = setting.username , setting );
        await page.$eval('#password', (el , setting ) => el.value = setting.password , setting );

    await Promise.all(
     page.$eval('form', form => form.submit()),
     page.waitForNavigation()
    )


        await page.goto( 'http://example.com/dashboard'  );



    resolve();

}).then(() => {

        console.log( ' -> don!  '  );
        page.close();

    })
    .catch(() => {

        console.log( ' -> somethign went wrong !');
        page.close();

    })


}

我明白了

(node:14812) UnhandledPromiseRejectionWarning: TypeError: undefined is not a function
    at Function.all (<anonymous>)
    at Promise (D:\wamp\www\gatewayCard\robot\server.js:287:23)
    at <anonymous>
    at process._tickCallback (internal/process/next_tick.js:188:7)
(node:14812) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 3)
(node:14812) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
javascript puppeteer
1个回答
2
投票

之所以发生这种情况,是因为导航可能会在您等待之前提交。

使用Promise.all在一个承诺中使用submission和waitForNavigation,因此它将等待它们而不是一次一个。

await Promise.all(
 page.waitForNavigation(),
 page.$eval('form', form => form.submit())
)

要么,

await Promise.all(
 page.$eval('form', form => form.submit()),
 page.waitForNavigation()
)

要么应该工作。

编辑1:

编辑完全不是你的主要问题。您没有在代码中使用正确的异步...等待。这是一个更好的代码。

异步的美妙......等待功能是你可以做更少的代码和更好的可读性和可维护性。这是一把双刃剑,但如果使用得当,还是值得的。

async function open_tab(setting) {
  try {
    const page = await global_browser.newPage();
    await page.setViewport({
      width: 1000,
      height: 768
    });
    await page.goto('http://example.com/dashboard');
    await page.$eval('#username', (el, setting) => el.value = setting.username, setting);
    await page.$eval('#password', (el, setting) => el.value = setting.password, setting);
    await Promise.all(page.$eval('form', form => form.submit()), page.waitForNavigation());
    console.log(' -> don!  ');
    await page.close();
  } catch (error) {
    console.log(' -> somethign went wrong !', error);
    await page.close();
  }
}

编辑2:

在你的代码中

return await new Promise(async (resolve, reject ) => {

这在许多步骤上都是错误的。 async函数无论如何都返回一个promise,所以你在promise中返回一个promise,而不是捕获它并使用await。尽早查看您的代码,否则您很快就会面临巨大的问题。

看来你应该先了解一下异步等待。这里有一些有用的链接,这些将解释超时和您想要学习的一切。

© www.soinside.com 2019 - 2024. All rights reserved.