У меня есть проект, чтобы очистить продукты, приобретенные определенными клиентами, от внутренней 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 в консоли, чтобы убедиться, что я правильно прошагаю по логи c и получаю то, что ожидаю :
>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