简体   繁体   English

木偶:选择器中的方括号逸出

[英]Puppeteer: Escape square brackets in selector

I need to select elements with ids that contain square brackets. 我需要选择ID包含方括号的元素。

ie

#element[0]

However, I keep getting: 但是,我不断得到:

Error: failed to find element matching selector "element[0]" 错误:找不到与选择器“ element [0]”匹配的元素

I've escaped the element in the selector with \\ , but that doesn't work. 我已经用\\逃避了选择器中的元素,但这是行不通的。

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

Double backslash escapes don't work either. 双反斜杠转义符也不起作用。 ie: 即:

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

UPDATE: The element I'm trying to select: 更新:我正在尝试选择的元素:

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

NOTE: I get the same error even when I try to use the page.waitFor method with the query above. 注意:即使我尝试对上面的查询使用page.waitFor方法,我也会收到相同的错误。

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

You can use the CSS attribute selector in reference to the element's id attribute: 您可以使用CSS 属性选择器来引用元素的id属性:

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

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

Escaping using encoded data 使用编码数据转义

If you even try to do document.querySelector('#fruit[0]') on your browser, you will get same error. 如果您甚至尝试在浏览器上执行document.querySelector('#fruit[0]') ,也会遇到相同的错误。 The escape doesn't work because by the time puppeteer reads it, it is already parsed and doesn't have the same escaped value. 转义不起作用,因为到伪造者读取它时,它已经被解析并且没有相同的转义值。 Few ways to escape them. 逃脱它们的几种方法。

Say we have an element like this, 说我们有一个这样的元素,

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

Now if you want to use vanila JS, you can try the following, 现在,如果您想使用vanila JS,可以尝试以下方法,

在此处输入图片说明

Which reads the following: 内容如下:

< 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('#sample\5b 112\5d')
> 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>

As you can see above, the left bracket is 5b and right bracket is 5d , and we even had to escape that and had to put space so browser could parse it. 如您在上面看到的,左括号为5b ,右括号为5d ,我们甚至不得不转义该5d并不得不留出空间,以便浏览器可以解析它。

You should try out above codes and find which one works for your site. 您应该尝试上述代码,然后找到适合您网站的代码。

Real case scripts 真实案例脚本

Let's face it, your target website does not have value for the options. 面对现实,您的目标网站没有任何选择的价值。 The best way will be to select by text, shamelessly copying from this answer . 最好的方法是通过文本选择,从此答案中无耻地复制。

Also, I could escape it twice and get data without encoding them. 另外,我可以对它进行两次转义并获取数据,而无需对其进行编码。 After all, nodeJS is different than the browsers console, and everything will act differently when on a script. 毕竟,nodeJS与浏览器控制台不同,并且在使用脚本时,所有动作都将有所不同。

Source used for HTML, 用于HTML的源代码,

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

And puppeteer code used for testing, 还有用于测试的操纵up代码,

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();
});

在此处输入图片说明

You may be referencing the ID incorrectly. 您可能未正确引用ID。

If you're programmatically generating the IDs when creating the HTML elements (ie fruit[0] , fruit[1] ), then what's being stored is the value and not the reference. 如果您在创建HTML元素(例如fruit[0]fruit[1] )时以编程方式生成ID,则存储的是值而不是引用。

Example: I have an array fruit = [apple, banana] and I create an element... <button id=fruit[0]>Click me</button> If I want to select that button then I need page.select('#apple') instead of page.select('#fruit[0]') 示例:我有一个数组fruit = [apple, banana]并创建了一个元素... <button id=fruit[0]>Click me</button>如果要选择该按钮,则需要page.select('#apple') 代替 page.select('#fruit[0]')

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

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