Выход с использованием закодированных данных
Если вы даже попытаетесь сделать document.querySelector('#fruit[0]')
в своем браузере, вы получите ту же ошибку. Экранирование не работает, потому что к тому времени, когда кукловод читает его, он уже проанализирован и не имеет того же экранированного значения. Несколько способов избежать их.
Скажем, у нас есть такой элемент,
<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('#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>
Как вы можете видеть выше, левая скобка - 5b
, а правая скобка - 5d
, и нам даже пришлось убежать от этого и пришлось поставить пробел, чтобы браузер мог его проанализировать.
Вы должны попробовать приведенные выше коды и найти, какой из них подходит для вашего сайта.
Реальные сценарии
Посмотрим правде в глаза, ваш целевой сайт не имеет значения для параметров. Лучше всего будет выбрать по тексту, бесстыдно скопировав с этот ответ .
Кроме того, я мог дважды избежать этого и получать данные без их кодирования. В конце концов, nodeJS отличается от консоли браузера, и все будет работать по-разному в сценарии.
Источник, используемый для HTML,
<select id="sample[1]"><option>mango</option><option>apple</option></select>
И код кукловода, используемый для тестирования,
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();
});