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' );
我需要 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' );