#node.js #puppeteer #chromium
#node.js #puppeteer #chromium
Вопрос:
Итак, у меня запускается следующий код
this.browser = await puppeteer.launch( { headless: false, devtools: true, slowMo: 200});
this.page = await this.browser.newPage();
await this.page.goto(pageUrl);
let result = await this.page.evaluate(() => {
const labels = document.querySelectorAll("li.product-item");
let productList = [];
for(let product of labels) {
productList.push(product);
}
debugger;
//filter only product stacks that have a price
const productStacks = productList.filter(product => product.querySelector("span.price-wrapper") !== null);
let results = productStacks.map(product => {
return product.querySelector("span.price-wrapper").getAttribute("data-price-amount");
});
return results;
});
Итак, chromium запускается и останавливается на соответствующем коде (насколько я могу судить), я даже вижу, как локальные переменные заполняются ожидаемым результатом и пошагово просматривают код, однако открытый файл puppeteer_evaluation_script не заполняется сценарием оценки и остается с содержимым, поэтому я прохожу черезслепой.
//# sourceURL=__puppeteer_evaluation_script__
Иногда через много минут он действительно заполняется кодом. Я понятия не имею, что не так, я пытался обновить последние lts узлов и puppeteer, но у них такое же поведение.
Комментарии:
1. Привет, я уже некоторое время безуспешно пытаюсь заставить это работать — вам удалось найти решение?
2. Нет, я этого не делал, и удивлен, что я чувствую, что никто другой не сталкивался с этой проблемой, но вот вы здесь!
Ответ №1:
Я не знаю, что вызывает эту проблему, но вот пара возможных решений.
Чтобы избежать получения:
//# sourceURL=__puppeteer_evaluation_script__
Вы можете предоставить функцию:
const puppeteer = require('puppeteer');
var browser = null;
var page = null;
(async () =>
{
browser = await puppeteer.launch(
{
headless: false,
devtools: true,
});
page = await browser.newPage();
await page.goto("https://google.com/");
// Expose a function
page.exposeFunction("nothing", () => null);
await page.evaluate(async function()
{
debugger;
console.log("Do task");
});
})();
На случай, если в будущем произойдет сбой. Я создал оболочку для использования eval()
, поскольку исходный код появляется с использованием этого.
Он работает как с функциями синхронизации, так и с асинхронными функциями и поддерживает передачу аргументов и возвращаемые значения.
function evaluateFixed(page, realFunction)
{
return page.evaluate(async function(realFunction, args)
{
var func = eval(`(${realFunction})`);
if(func.constructor.name === "AsyncFunction")
return await func(...args);
else
return func(...args);
},
realFunction.toString(), Array.from(arguments).slice(2));
}
(async () =>
{
browser = await puppeteer.launch(
{
headless: false,
devtools: true,
});
page = await browser.newPage();
await page.goto("https://google.com/");
console.log("Doing test");
let res = await evaluateFixed(page, async function(x, y, z)
{
debugger;
console.log("Do task", x, y, z);
function sleep(amount)
{
return new Promise((resolve) => setTimeout(resolve, amount));
}
for(let i = 0; i < 10; i )
{
console.log("on seconds", i);
await sleep(1000);
}
return { "fee": "foo" };
}, 1, "two", { "three": 3});
console.log("Res 1", res);
res = await evaluateFixed(page, () =>
{
debugger;
return 1 2;
});
console.log("Res 2", res);
})();
Комментарии:
1. пробовал оба решения, тот же результат пустой //# sourceURL=__puppeteer_evaluation_script__
2. вы получаете ту же пустую страницу сценария на вкладке «Источники», но вы можете видеть фактический код в окне стека вызовов, что для меня достаточно хорошо — спасибо