如何使用 Puppeteer 从输入中删除现有文本?

Posted

技术标签:

【中文标题】如何使用 Puppeteer 从输入中删除现有文本?【英文标题】:How to delete existing text from input using Puppeteer? 【发布时间】:2019-03-08 22:06:39 【问题描述】:

我正在尝试在包含当前记录标题的可编辑输入中测试修改文本 - 我希望能够测试编辑此类文本,并将其替换为其他内容。

我知道我可以使用await page.type('#inputID', 'blah'); 将“blah”插入文本框(在我的情况下,现有文本仅附加“blah”),但是,我找不到任何允许删除的页面方法1或替换现有文本。

【问题讨论】:

How to clear an item value in puppeteer的可能重复 【参考方案1】:

你可以使用page.evaluate来操作你认为合适的DOM:

await page.evaluate( () => document.getElementById("inputID").value = "")

但有时仅操作给定字段可能还不够(目标页面可能是带有事件侦听器的 SPA),因此最好模拟真实的按键操作。以下示例来自 puppeteer 的 Github 中的 the informative issue 关于此任务。

在这里,我们按Backspace 的次数与该字段中的字符一样多:

const inputValue = await page.$eval('#inputID', el => el.value);
for (let i = 0; i < inputValue.length; i++) 
  await page.keyboard.press('Backspace');

另一个有趣的解决方案是单击目标字段 3 次,以便浏览器选择其中的所有文本,然后您可以输入您想要的内容:

const input = await page.$('#inputID');
await input.click( clickCount: 3 )
await input.type("Blah");

【讨论】:

await input.click( clickCount: 3 ) ,这很有趣!就像我们使用浏览器一样! 请注意,三次点击解决方案不适用于包含多行的文本区域,因为它只会突出显示一个。 @vsync 2 次点击选择一个单词,3 次点击选择输入中的所有文本,这就是问题所在:) Backspace 的想法很好,但现在(Puppeteer 2)它必须是 await page.keyboard.press('Backspace'); 而不是 await page.press('Backspace'); await input.click( clickCount: 4 ) 用于多行选择【参考方案2】:

您可以使用page.keyboard 方法更改输入值,也可以使用page.evaluate()

替换所有文本:

// Using page.keyboard:

await page.focus('#example');
await page.keyboard.down('Control');
await page.keyboard.press('A');
await page.keyboard.up('Control');
await page.keyboard.press('Backspace');
await page.keyboard.type('foo');

// Using page.evaluate:

await page.evaluate(() => 
  const example = document.getElementById('example');
  example.value = 'foo';
);

附加文字:

// Using page.keyboard:

await page.focus('#example');
await page.keyboard.press('End');
await page.keyboard.type(' bar qux');

// Using page.evaluate:

await page.evaluate(() => 
  const example = document.getElementById('example');
  example.value += ' bar qux';
);

退格最后一个字符:

// Using page.keyboard:

await page.focus('#example');
await page.keyboard.press('End');
await page.keyboard.press('Backspace');

// Using page.evaluate:

await page.evaluate(() => 
  const example = document.getElementById('example');
  example.value = example.value.slice(0, -1);
);

删除第一个字符:

// Using page.keyboard:

await page.focus('#example');
await page.keyboard.press('Home');
await page.keyboard.press('Delete');

// Using page.evaluate:

await page.evaluate(() => 
  const example = document.getElementById('example');
  example.value = example.value.slice(1);
);

【讨论】:

Mac 对应的 Windows Control + A 是 Command + A。 对于跨平台键盘解决方案,您可以改为使用page.keyboard.down('Shift')page.keyboard.press('End'),然后是page.keyboard.press('Backspace') 替换所有文本不适用于 Mac,因为在 Mac 中 ctrl + A keystroke 不会选择整个文本,而是将光标放在字段的开头【参考方案3】:

如果您对模拟任何关键事件不感兴趣,您还可以使用 puppeteer 的 page.$eval 方法作为删除文本区域值的简洁方法...

await page.$eval('#inputID', el => el.value = '');
await page.type('#inputID', 'blah');

...甚至一步完全替换值,无需模拟后续输入:

await page.$eval('#inputID', el => el.value = 'blah');

【讨论】:

【参考方案4】:

这非常适合“仅清除”方法:

const input = await page.$('#inputID');
await input.click( clickCount: 3 )
await page.keyboard.press('Backspace')

【讨论】:

【参考方案5】:

以上答案存在 ESLint 问题。 以下通过 ESLint 验证的解决方案:

await page.evaluate(
  (selector) =>  (document.querySelector(selector).value = ''); ,
  inputBoxSelector,
);

【讨论】:

【参考方案6】:

好吧,您想要删除现有文本的原因通常可能是想要替换它。

您可以使用page.evalute

let title = getTitle()
let selector = getSelector()

await page.evaluate(
  (selector, title) => 
    let el = document.querySelector(selector)
    if ('value' in el) el.value = title
    else el.innerText = title
  ,
  selector, title
)

【讨论】:

【参考方案7】:

someField.type("");

在输入内容之前传递空字符串。

这对我有用。

【讨论】:

【参考方案8】:

使用模拟击键的Keyboard API:

await page.focus(css);            // CSS selector of the input element
await page.keyboard.down('Shift'); 
await page.keyboard.press('Home');
await page.keyboard.up('Shift');  // Release the pressed 'Shift' key
await page.keyboard.press('Backspace');

这个按键是跨平台的,而不是使用 ctrl + A(在 Mac 中不能选择输入字段中的所有字符)

【讨论】:

【参考方案9】:

对我来说最干净的方式是:

设置
const clearInput = async (page,  selector ) => 
  const input = await page.$(selector)
  await input.click( clickCount: 3 )
  await page.keyboard.press('Backspace')

用法
const page = await context.newPage()

await clearInput(page,  selector: 'input[name="session[username_or_email]"]' )
await clearInput(page,  selector: 'input[name="session[password]"]' )

【讨论】:

以上是关于如何使用 Puppeteer 从输入中删除现有文本?的主要内容,如果未能解决你的问题,请参考以下文章

使用 Puppeteer 如何从目录上传随机文件并将其删除?

所以我刚刚创建了一个文本文件并使用 with 循环从现有文件中复制了文本。如何在同一个 prog 中打开新创建的文件?

已在Puppeteer中定义函数后如何调用该函数

如何在 Puppeteer 中点击文本?

如何使用 Puppeteer 填充输入字段?

如何从输入文本中删除选定的文本?