首页 > 解决方案 > puppeteer - page.type() 不起作用,但 element.setAttribute() 起作用?

问题描述

我想使用 Puppeteer 在输入字段中输入值。根据文档,这似乎很简单(来自文档的示例):

await page.type('#mytextarea', 'Hello'); // Types instantly
await page.type('#mytextarea', 'World', {delay: 100}); // Types slower, like a user

所以我创建了以下测试脚本:

const puppeteer = require('puppeteer');

(async () => {

  const browser = await puppeteer.launch({headless: false}); // devtools: true
  const page = await browser.newPage();
  await page.goto('https://mycoolsite/index.html');

  page.on('console', msg => console.log(new Date().toISOString() + ' ' + msg._text));

  const selector = '#barcode';
  await page.waitForSelector(selector);
  await page.type(selector, "1234");

})();

它适用于 page.type() 行。意思是,它启动一个 Chromium 实例,转到正确的 URL,在日志中显示来自控制台的预期输出。但不在字段中键入值。我在节点输出或浏览器控制台输出中都没有看到任何错误。

为了排除静默失败,我将选择器名称更改为不存在的名称(例如,“#qwertyuiop”)并按预期出现故障。

如果我用await page.type(selector, "1234");以下内容替换该行,我找到了一种解决方法:

  const element = await page.$(selector);
  await page.evaluate(element => { element.setAttribute('value', 1234); }, element);

这感觉就像一个黑客。为什么 puppeteer 使用 page.evaluate 正确设置值而不是记录的 page.type 方法?

标签: puppeteer

解决方案


弄清楚了...

输入包含在隐藏元素中。

换行

await page.waitForSelector(selector);

await page.waitForSelector(selector, {visible: true, timeout: 3000 });

解决了。显然,在 page.type() 起作用之前元素必须是可见的,而通过属性设置元素的值并不关心,只要它是 DOM 的一部分。

(来自文档 - visible 选项导致 puppeteer 等待元素出现在 DOM 中可见。默认为 false。)


推荐阅读