Puppeteer:在选择器中转义方括号

Puppeteer: Escape square brackets in selector

我需要 select 个 ID 包含方括号的元素。

#element[0]

但是,我不断收到:

Error: failed to find element matching selector "element[0]"

我已经在 select 或 \ 中转义了元素,但这不起作用。

page.select("#fruit\[0\]", "apples")

双反斜杠转义也不起作用。即:

page.select("#fruit\[0\]", "apples")

更新:我正在尝试 select:

的元素
<select id="fruit[0]">
  <option>Please make a selection</option>
  <option>apples</option>
</select>

注意:即使我尝试对上面的查询使用 page.waitFor 方法,我也会遇到同样的错误。

使用编码数据转义

如果您甚至尝试在浏览器上执行 document.querySelector('#fruit[0]'),您也会遇到同样的错误。转义不起作用,因为在 puppeteer 读取它时,它已经被解析并且没有相同的转义值。逃避他们的方法很少。

假设我们有这样一个元素,

<a href="/" id="sample[112]">Bar</a>

现在如果你想使用vanila JS,你可以试试下面的方法,

内容如下:

< document.querySelector(CSS.escape('#sample[112]'))
> null

< document.querySelector('#sample[112]')
> Uncaught DOMException: Failed to execute 'querySelector' on 'Document': '#sample[112]' is not a valid selector.

< document.querySelector('#sampleb 112d')
> ncaught DOMException: Failed to execute 'querySelector' on 'Document': '#sampleb 112d' is not a valid selector.

< document.querySelector('#sample\5b 112\5d')
> <a href="/" id="sample[112]">Bar</a>

正如你在上面看到的,左括号是 5b,右括号是 5d,我们甚至不得不转义它,不得不放 space 以便浏览器可以解析它。

您应该尝试以上代码并找出适合您网站的代码。

真实案例脚本

让我们面对现实吧,您的目标网站对选项没有价值。最好的方法是通过文本到 select,无耻地从 this answer.

复制

此外,我可以将其转义两次并在不对数据进行编码的情况下获取数据。毕竟,nodeJS 与浏览器控制台不同,在脚本上一切都会有所不同。

用于 HTML、

的来源
<select id="sample[1]"><option>mango</option><option>apple</option></select>

以及用于测试的 puppeteer 代码,

const puppeteer = require("puppeteer");

function setSelectByText(selector, text) {
  // Loop through sequentially//
  const ele = document.querySelector(selector);
  console.log(ele);

  for (let ii = 0; ii < ele.length; ii++) {
    if (ele.options[ii].text == text) {
      // Found!
      ele.options[ii].selected = true;
      return true;
    }
  }
  return false;
}

puppeteer.launch().then(async browser => {
  console.log("Opening browser");
  const page = await browser.newPage();

  console.log("Going to site");
  await page.goto("http://0.0.0.0:8080"); // temporary website created for testing

  await page.evaluate(setSelectByText, "#sample\[1\]", "apple"); // we can use this over and over, without creating a separate function, just passing them as arguments

  await page.screenshot({ path: "test.png" });

  await browser.close();
});

您引用的 ID 可能不正确。

如果您在创建 HTML 元素(即 fruit[0]fruit[1])时以编程方式生成 ID,则存储的是 值和不是参考。

示例:我有一个数组fruit = [apple, banana],我创建了一个元素... <button id=fruit[0]>Click me</button> 如果我想要 select 那个按钮,那么我需要 page.select('#apple') 而不是 page.select('#fruit[0]')

使用[id="fruit[0]"]:

您可以使用 CSS attribute selector 引用元素的 id 属性:

await page.waitFor( '[id="fruit[0]"]' );

await page.select( '[id="fruit[0]"]', 'apples' );