gpt4 book ai didi

javascript - 一旦用户从登录移动到主页,我如何在 puppeteer 中引用当前页面对象?

转载 作者:行者123 更新时间:2023-12-05 07:33:20 31 4
gpt4 key购买 nike

所以我尝试使用 puppeteer 来自动化 Oracle 云应用程序中的一些数据输入功能。

截至目前,我可以启动云应用程序登录页面,输入用户名和密码凭据,然后单击登录按钮。登录成功后,Oracle 会为用户打开一个主页。一旦发生这种情况,如果我截图或执行页面。内容截图和内容 html 来自登录页面而不是主页。

如何始终引用用户所在的当前页面?

这是到目前为止的基本代码。

const puppeteer = require('puppeteer');
const fs = require('fs');

(async () => {
const browser = await puppeteer.launch({headless: false});
let page = await browser.newPage();
await page.goto('oraclecloudloginurl', {waitUntil: 'networkidle2'});
await page.type('#userid', 'USERNAME', {delay : 10});
await page.type('#password', 'PASSWORD', {delay : 10});
await page.waitForSelector('#btnActive', {enabled : true});
page.click('#btnActive', {delay : 1000}).then(() => console.log('Login Button Clicked'));

await page.waitForNavigation();
await page.screenshot({path: 'home.png'});
const html = await page.content();
await fs.writeFileSync('home.html', html);
await page.waitFor(10000);
await browser.close();
})();

有了这个,用户可以正常登录并显示主页。但是之后当我尝试截取主页并呈现 html 内容时出现错误。好像是页面变了,我指的是旧页面。如何引用当前页面的上下文?

错误如下:

(node:14393) UnhandledPromiseRejectionWarning: Error: Protocol error (Runtime.callFunctionOn): Cannot find context with specified id undefined

最佳答案

这段代码看起来有问题有两个原因:

page.click('#btnActive', {delay : 1000}).then(() => console.log('Login Button Clicked'));

await page.waitForNavigation();

第一个问题是 page.click().then() 分离出一个完全独立的 promise 链:

page.click() --> .then(...)
|
v
page.waitForNavigation()
|
v
page.screenshot(...)
|
v
...

这意味着触发导航的点击和导航是并行运行的,永远不能重新加入同一个 promise 链。这里通常的解决方案是将它们绑定(bind)到同一个 promise 链中:

// Note: this code is still broken; keep reading!
await page.click('#btnActive', {delay : 1000});
console.log('Login Button Clicked');
await page.waitForNavigation();

这遵循了不混合使用 thenawait 的原则,除非你有充分的理由这样做。

但是上面的代码仍然是错误的,因为 Puppeteer 要求在触发导航的事件被触发之前设置 waitForNavigation() promise 。修复是:

await Promise.all([
page.waitForNavigation(),
page.click('#btnActive', {delay : 1000}),
]);

const navPromise = page.waitForNavigation(); // no await
await page.click('#btnActive', {delay : 1000});
await navPromise;

遵循这种模式,Puppeteer 不应再对其上下文感到困惑。


小笔记:

  • 'networkidle2' 很慢而且可能没有必要,尤其是对于您即将离开的页面。我会默认为 'domcontentloaded'
  • await page.waitFor(10000);page.waitForTimeout() 一起被弃用,尽管我意识到这是一篇较旧的帖子。

关于javascript - 一旦用户从登录移动到主页,我如何在 puppeteer 中引用当前页面对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50658786/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com