简体   繁体   English

puppeteer 错误未知键:“”尝试按空格键时

[英]puppeteer Error Unknown key: " " when trying to press space key

I was trying to make a fun project by automating a typing test using puppeteer, but when I want to press space this error pops up我试图通过使用 puppeteer 自动进行打字测试来制作一个有趣的项目,但是当我想按空格时,会弹出这个错误

D:\scraping\puppeteer tut\node_modules\puppeteer\lib\cjs\puppeteer\common\assert.js:28
        throw new Error(message);
              ^

Error: Unknown key: " "
    at assert (D:\scraping\puppeteer tut\node_modules\puppeteer\lib\cjs\puppeteer\common\assert.js:28:15)
    at Keyboard._Keyboard_keyDescriptionForString (D:\scraping\puppeteer tut\node_modules\puppeteer\lib\cjs\puppeteer\common\Input.js:265:28) 
    at Keyboard.down (D:\scraping\puppeteer tut\node_modules\puppeteer\lib\cjs\puppeteer\common\Input.js:112:119)
    at Keyboard.press (D:\scraping\puppeteer tut\node_modules\puppeteer\lib\cjs\puppeteer\common\Input.js:231:20)
    at D:\scraping\puppeteer tut\typingTest.js:37:34
    at processTicksAndRejections (node:internal/process/task_queues:96:5)

The code for the project is该项目的代码是

const puppeteer = require("puppeteer");

(async () => {
  const browser = await puppeteer.launch({
    headless: false,
    defaultViewport: false
  });
  const page = await browser.newPage();
  await page.goto("https://www.speedtypingonline.com/typing-test", {
    waitUntil: "load"
  });
  const word = await page.evaluate(() => {
    let lineDivArr = document.querySelectorAll(".blockLines");
    let charArr = [];
    let ActualChar = [];
    lineDivArr.forEach((line) => {
      charArr.push(line.querySelectorAll('span'));
    })

    charArr.forEach((char) => {
      char.forEach((c) => {
        ActualChar.push(c.outerText);
      })
    })
    return ActualChar;
  })
  for (const element of word) {
    if (element == String.fromCharCode(32)) {
      await page.keyboard.press(String.fromCharCode(32));
    } else await page.keyboard.press(element);
  }
})();

In addition to the above error, I occasionally encounter this error mentioned here :除了上面的错误,我偶尔也会遇到这里提到的这个错误:

Error: We either navigate top level or have old version of the navigated frame错误:我们要么导航顶层,要么拥有旧版本的导航框架

Kindly help me resolve the issue.请帮我解决问题。

I'm happy to see a site that consistently reproduces the "We either navigate top level or have old version of the navigated frame" error.我很高兴看到一个网站不断重现“我们导航顶层或拥有旧版本的导航框架”错误。 I'm not sure I've 100% solved it, but when I navigate to the page without ad blockers, there appear to be a few reloads that seem triggered by iframes /Google (ads|analytics) junk.我不确定我是否 100% 解决了它,但是当我导航到没有广告拦截器的页面时,似乎有一些重新加载似乎是由 iframe/Google(广告|分析)垃圾触发的 After blocking those requests and deleting the iframes, things are reliable enough for a toy script.在阻止这些请求并删除 iframe 之后,对于玩具脚本来说,事情已经足够可靠了。

Next, the space character issue is caused by the site using rich text spaces (and other non-ASCII characters).其次,空格字符问题是由站点使用富文本空格(和其他非 ASCII 字符)引起的。 They look like ASCII but aren't (debug with letter.charCodeAt() to see that they're out of range).它们看起来像 ASCII 但不是(使用letter.charCodeAt()进行调试以查看它们超出范围)。 The solution is to detect these characters and fire the ASCII equivalent.解决方案是检测这些字符并触发 ASCII 等效字符。 I only did it for the character code 160 space, which is enough to get 99-100% accuracy on most tests.我只为字符代码 160 空格做了它,这足以在大多数测试中获得 99-100% 的准确度。

Here's my code so far.到目前为止,这是我的代码。 Other known issues:其他已知问题:

  • Occasional assertion failure probably related to the "We navigate..." error, but without any message (I suspect my iframe removal code has a race condition).偶尔的断言失败可能与“我们导航...”错误有关,但没有任何消息(我怀疑我的 iframe 删除代码有竞争条件)。 I didn't look into it deeply.我没有深入研究它。
  • Technically, there's a race condition on the .nxtLetter element but in practice I think it's virtually impossible for the browser to hang long enough that Puppeteer will manage to get two keystrokes in before the class moves to another element.从技术上讲, .nxtLetter元素存在竞争条件,但实际上我认为浏览器几乎不可能挂起足够长的时间,以至于 Puppeteer 在 class 移动到另一个元素之前设法获得两次击键。 Due to the complexity of the task, it's possible that things can get out of sync and fail--my goal was to get 95% in the ballpark rather than write a perfect bot.由于任务的复杂性,事情可能会不同步并失败——我的目标是在球场上获得 95%,而不是编写一个完美的机器人。
  • Selecting and typing one character at a time has a lot of process overhead.一次选择和输入一个字符会产生大量的过程开销。 I originally tried typing the whole text at once with page.type() but I ran into mistakes too easily, so I erred on the side of reliability.我最初尝试使用page.type()一次输入整个文本,但我太容易出错了,所以我在可靠性方面犯了错误。 Ditto for checking the stopping condition;同上用于检查停止条件; lots of wasted cycles here.这里有很多浪费的周期。 I'll leave it as an exercise to speed things up.我会把它作为一个练习来加快速度。
const puppeteer = require("puppeteer");

let browser;
(async () => {
  browser = await puppeteer.launch({headless: false});
  const [page] = await browser.pages();
  await page.setRequestInterception(true);
  page.on("request", request => {
    if (/google|cloudflare/.test(request.url())) {
      request.abort();
    }
    else {
      request.continue();
    }
  });
  await page.goto("https://www.speedtypingonline.com/typing-test", {
    waitUntil: "domcontentloaded"
  });
  await page.evaluate(`
    [...document.querySelectorAll("iframe")]
      .forEach(e => e.remove());
  `);
  const letterSel = ".nxtLetter"
  await page.waitForSelector(letterSel);

  while (!(await page.$("#WPM_Result span"))) {
    const letter = await page.$$eval(letterSel, els => {
      const letter = els.at(-1).textContent;
      return letter.charCodeAt() === 160 ? " " : letter;
    });
    await page.type(letterSel, letter, {delay: 0});
  }

  await page.screenshot({
    path: "typing-results.png",
    fullPage: true
  });
})()
  .catch(err => console.error(err))
  .finally(() => browser?.close())
;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM