Puppeteer 点击 Reddit 登录按钮

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

我在登录过程中选择按钮时遇到了 Puppeteer 的麻烦。我试图让它登录 Reddit,但登录按钮没有名称或 ID,并且可能会选择其他按钮。它还包含在其他元素中,所以我什至不确定该选择哪一个。我将在下面包含我的代码。有谁知道在输入用户名和密码后我可以做什么来按 Reddit.com 上的登录按钮?选择其他元素很容易,因为它们有 id。

const puppeteer = require ('puppeteer');

function sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}

async function loginToReddit(usernameText, passwordText){
    const browser = await puppeteer.launch({
        headless: false,
        defaultViewport: false,
        userDataDir: "./tmp"
    });
    const page = await browser.newPage();
    await page.goto('https://www.reddit.com/');
    await page.click('#login-button');

    sleep(2000).then(() => {
        enterCredentials(usernameText, passwordText, page);
    });
}

async function enterCredentials(usernameText, passwordText, page){
    await page.click('#login-username');
    await page.keyboard.type(usernameText,{
        delay: 50,
    });
    await page.click('#login-password');
    await page.keyboard.type(passwordText,{
        delay: 50,
    });
    sleep(2000).then(() => {
        selectLoginButton(page);
    });
}

async function selectLoginButton(page) {
    page.waitForNavigation();
    //const xp = 'faceplate-tracker button';
    const xp = 'faceplate-tracker > button';
    const el = await page.waitForSelector(xp);
    await el.click();
}

loginToReddit('username', 'password');
javascript puppeteer
1个回答
0
投票

在进一步使用 Puppeteer 之前,我建议先温习一下您的 Promise 基础知识。这里的代码在某些地方没有多大意义。 不要混淆

then
await
,并确保
await
所有承诺。没有
page.waitForNavigation();
await
没有任何作用。

还要避免过早的抽象——这些额外的函数只会让事情变得正确变得更加困难。一旦有了工作代码,就可以将其分解出来。

别睡觉。使用精确的谓词。

请注意,该页面有许多影子根,因此您需要阅读相关内容并熟悉

>>>
选择器。

这是自动化此操作的一种方法:

const puppeteer = require("puppeteer"); // ^23.6.0

const url = "<Your URL>;

let browser;
(async () => {
  browser = await puppeteer.launch({headless: false});
  const [page] = await browser.pages();
  await page.goto(url, {waitUntil: "domcontentloaded"});
  await page.locator("#login-button").click();
  const un = await page.waitForSelector("#login-username");
  await un.type("foo");
  await page.type("#login-password", "baz");

  for (let tries = 0; tries < 50; tries++) {
    try {
      await page.keyboard.press("Enter");

      // just for this demo; use some other
      // 'success' selector for the actual automation
      await page.waitForSelector(
        ">>> ::-p-text(Invalid username or password)",
        {timeout: 100}
      );
      break;
    } catch {
      //
    }
  }

  await page.screenshot({path: "proof.png"});
})()
  .catch(err => console.error(err))
  .finally(() => browser?.close());

通常情况下,这不会这么棘手,但是输入后立即按 Enter 不会提交表单,因此我选择轮询直到 Enter 按键注册 - 也许不是最好的解决方案,但对于初学者来说已经足够了。

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