不寻常的傀儡师行为

Unusual Puppeteer behavior

提问人:Saloni Saraiya 提问时间:10/20/2023 最后编辑:Saloni Saraiya 更新时间:11/2/2023 访问量:79

问:

我正在使用 Puppeteer 无头打开网络浏览器以在 JS 中操作一个网站。网站在处理前需要登录。因此,它会打开一个弹出窗口并在登录时将其关闭。我正在尝试通过 Puppeteer 在弹出窗口中填写电子邮件和密码以登录。有时它运行良好,有时它无法填充电子邮件。

我尝试了各种选择。此外,它在脚本中完美运行。但是当我通过 API 访问脚本时,问题就来了。

可能的原因是什么?

const express = require('express');
const dotenv = require('dotenv');
const cors = require('cors');
dotenv.config({ path: '.env' });
global.__appRootDir = __dirname;

app.use(cors());
app.use(express.json({ limit: '50mb' }));

const PORT = process.env.PORT ?? '3059'
const HOST = process.env.HOST ?? 'localhost';

app.get('/', (req, res) => {
    res.send('server is responding')
})

app.post('/conversion', conversion)

const conversion = async (req, res) => {

    try {
        const browser = await puppeteer.launch({
            headless: true
        });
        const page = await browser.newPage();

        await page.goto(process.env.SITE_URL, { waitUntil: 'domcontentloaded' });

        await page.waitForSelector('button[id="login"]');
        await page.click('button[id="login"]');

        console.log("Popup Opened");

        const newPagePromise = new Promise(x => browser.once('targetcreated', target => x(target.page())));
        const popup = await newPagePromise;

        console.log("Find Inputs");
        const usernameInput = await popup.waitForSelector('input[id="username"]', { timeout: 30000 });
        await usernameInput.type(process.env.USERNAME)

        await popup.keyboard.press('Enter')

        const passwordInput = await popup.waitForSelector('input[id="password"]', { timeout: 30000 });
        await passwordInput.type(process.env.PASSWORD)

        console.log("Form  Filled");
        await popup.keyboard.press('Enter')

        // Create a promise that resolves when the popup page is closed
        const popupClosedPromise = new Promise((resolve) => {
            popup.once('close', () => {
                resolve()
            })
        })

        // Wait for the popup page to close
        await popupClosedPromise
        console.log("popup closed");

        console.log('login done')

        // next process - works perfectly.


    } catch (error) {
        console.error(error)
        return res.status(500).json({ message: error.message })
    }
}

// listen for requests
app.listen(PORT, HOST, () => {
    console.log(`Server is listening on port ${HOST}:${PORT}`);
});

站点 URL 为:https://magicul.io/

任何用户名和密码都可用于测试。这里的问题是,用户名和密码没有填写在字段中。您可以使用任何文本进行测试。

有时,它运行良好,有时,它在打印“查找输入”后停止。

JavaScript 节点.js 谷歌浏览器 傀儡师

评论

0赞 ggorlen 11/1/2023
明白了。有一件事看起来很奇怪,可能无关紧要,那就是它没有在行动之前设置。我会把 the 放在 listener 之后,而不是 the 前面。当您说“打印”查找输入“后停止”时,特定行是否超时?如果是这样,究竟是哪一个?popupClosedPromiseawait popup.keyboard.press('Enter')
0赞 Saloni Saraiya 11/1/2023
不,没有什么超时。执行停止,即使经过大量等待也没有任何反应
0赞 ggorlen 11/1/2023
感谢您添加代码。这很奇怪,因为那个区域的所有电话都是剧作家的电话,它们都有一个计时器,所以它们最终应该会抛出一个错误。没有对任何未包含的地方的呼叫,对吧?setDefaultTimeout(0)
0赞 Saloni Saraiya 11/2/2023
不,仅此而已。没有额外的代码。
0赞 Saloni Saraiya 11/2/2023
我今天在代码中为弹出窗口的图像标签(徽标)添加了waitforselector。将在接下来的 2 天内观察它。

答:

0赞 Lucas 10/20/2023 #1

您是否设置了等待此组件的时间限制?尝试设置超时。可以使用 waitForSelector 和 waitForTimeout。 可能是它没有出现,也可能是有一些东西阻止了它被填充,你必须等待一定的时间才能尝试在它上运行一些东西。

评论

1赞 ggorlen 10/24/2023
不鼓励超时
0赞 Lucas 10/27/2023
@SaloniSaraiya 为什么 waitForSelector 没有按预期工作?