hre*_*tic 2 javascript puppeteer
我有点困惑,page.waitForNavigation我知道它是什么,它是做什么的,但是我根据互联网速度获得了不同的结果(这就是我认为的因素)
想象一下这段代码
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' );
Run Code Online (Sandbox Code Playgroud)
它填写登录表单,提交登录表单,等待表单提交,然后重定向到仪表板
这在我的本地主机上工作正常,我的互联网速度较慢(与服务器比较),但是当我将其上传到服务器时我得到了
Error: Navigation Timeout Exceeded: 30000ms exceeded
Run Code Online (Sandbox Code Playgroud)
在服务器上,如果我await page.waitForNavigation();从代码中删除并重定向到仪表板,则可以正常工作
但是现在在localhost上,我可以重定向到仪表板,然后才能提交表单...所以我得到you cant see dashboard , your not logged in了这样的信息
我认为决定因素是互联网的速度
在服务器上,我的速度非常快,因此可以立即提交表单,并且await page.waitForNavigation()在行之前完成了表单,因此出现导航超时错误
但是在速度较慢的localhost上,需要更长的时间来提交表单,因此,我需要await page.waitForNavigation()在提交表单后才能拥有表单,否则我将被重定向到仪表板,然后表单才有机会提交
因此,即时通讯正在从有丰富经验的人那里寻求与puppeteer合作的建议,以解决这种情况……正确地知道,我在服务器或本地主机上运行时仍在编辑我的代码……这确实很烦人!
使用后
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();
})
}
Run Code Online (Sandbox Code Playgroud)
我得到
(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.
Run Code Online (Sandbox Code Playgroud)
发生这种情况是因为导航可能会在您等待之前提交时进行。
使用Promise.all在一个promise中使用submit和waitForNavigation ,因此它将等待两个而不是一次。
await Promise.all([
page.waitForNavigation(),
page.$eval('form', form => form.submit())
])
Run Code Online (Sandbox Code Playgroud)
要么,
await Promise.all([
page.$eval('form', form => form.submit()),
page.waitForNavigation()
])
Run Code Online (Sandbox Code Playgroud)
两者都应该工作。
编辑1:
该编辑完全脱离了您的主要问题。您没有在代码中使用适当的async ... await。这是一个更好的代码。
async ... await函数的优点是您可以减少代码编写,并提高可读性和可维护性。这是一把双刃剑,但如果使用得当,则值得。
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();
}
}
Run Code Online (Sandbox Code Playgroud)
编辑2:
在您的代码中
return await new Promise(async (resolve, reject ) => {
Run Code Online (Sandbox Code Playgroud)
这在许多步骤上都是错误的。异步函数无论如何都会返回一个promise,因此您要在一个promise中返回一个promise,而不会捕获它并对其使用wait。尽早检查您的代码,否则您很快就会面临巨大的问题。
看来您应该先了解更多有关异步等待的知识。这是一些对您有用的链接,这些链接将说明超时以及您想学习的所有内容。