У меня есть проект по очистке продуктов, приобретенных определенными клиентами, из внутренней CRM. В этой CRM используется много динамически загружаемых плиток, поэтому согласованных имен классов не так много (у многих есть идентификатор, случайным образом добавляемый при каждой загрузке страницы), а также есть много разных отчетов / элементов на странице с тем же именем класса, поэтому Я не могу запросить селектор элементов на всей странице.
Я определил "родительский" элемент, который мне нужен, через xpath. Затем я хочу развернуть и получить innerText только тех детей, которые соответствуют селектору запроса (в большинстве потоков, которые я вижу, люди используют селектор запросов на всей странице, это приведет к результатам из меню, которые мне не нужны).
Я могу сделать это в обычном Javascript в консоли браузера, просто не могу понять, как это сделать в Node / Puppeteer. Вот что у меня есть на данный момент:
//Getting xpath of the "box" that contains all of the product tiles that a customer has
const productsBox = await page.$x("/html/body/blah/blah/blah");
Вот где он ломается. Я не очень хорошо знаком с некоторым синтаксисом и не разбираюсь в документации Puppeteer, но я пробовал несколько разных методов (мне также не хватает функций для использования формата =>. В документации Puppeteer есть пример того, что я пытаюсь сделать , но я пробовал с той же структурой, и она тоже ничего не вернула):
//Tried using the elementHandle.$$eval approach on the zero index of my xpath results,
//but doesn't return anything when I console.log(productsList)
const productsList = await productsBox[0].$$eval('.title-heading', function parseAndText (products) {
productsList=[];
for (i=0; i<products.length; i++) {
productsList.push(products[i].innerText.trim());
}
return productsList;
}
);
//Tried doing the page.$$eval approach with selector, passing in the zero index of my xpath
const productsList = await page.$$eval('.title-heading', function parseAndText (products) {
productsList=[];
for (i=0; i<products.length; i++) {
productsList.push(products[i].innerText.trim());
}
return productsList;
}, productsBox[0]
//Tried the page.evaluate and then page.evaluateHandle approach on the zero index of my xpath,
//doing the query selection inside the evaluation and then doing something with that.
let productsList= await page.evaluateHandle(function parseAndText(productsBoxZero) {
productsInnerList = productsBoxZero.querySelectorAll(".title-heading");
productsList=[];
for (i=0; i<productsInnerList.length; i++) {
productsList.push(productsInnerList[i].innerText.trim());
//Threw a console log here to see if it does anything,
//But nothing is logged
console.log("Pushed product " + i + " into the product list");
}
return productsList;
}, productsBox[0]);
Что касается вывода, я записал в консоль некоторые переменные и получил следующее:
productsBox is JSHandle@node
productsBox[0] is JSHandle@node
productList is
Для сравнения, я делал это параллельно через Javascript в консоли, чтобы убедиться, что я правильно выполняю логику и получаю то, что ожидаю:
>productsBox=$x("/html/body/blah/blah/blah");
>productsInnerList=productsBox[0].querySelectorAll(".title-heading");
>productsInnerList.length;
//2, and this customer has 2 products
>productsList=[];
>for (i=0; i<productsInnerList.length; i++) {
productsList.push(productsInnerList[i].innerText.trim());
};
>console.log(productsList)
>["Product 1", "Product 2"]
Спасибо, что дочитали до этого места, и ценю вашу помощь!
[Редактировать]
Для дополнительного исследования я попытался использовать page.evaluateHandle и до сих пор пытался регистрировать свои переменные:
productsBox is JSHandle@node
productsBox[0] is JSHandle@node
productList is JSHandle@array
Это прогресс. Я пытался сделать: let productsText=await productsList.jsonValue();
Но когда я пытаюсь вывести, я ничего не получаю:
await console.log("productsText is " + productsText);
productsBox is JSHandle@node
productsBox[0] is JSHandle@node
productList is JSHandle@array
productsText is