Reputation: 1177
I'm trying to use Puppeteer to find if an array of strings exist on a webpage. I'm using this code:
runner.exec(
'php -r \'$translations = include("translations.php"); print json_encode($translations);\'',
function (err, stdout, stderr) {
var translations = JSON.parse(stdout);
var values = Object.values(translations);
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('https://example.com');
values.forEach(element => {
try {
page.$$eval('body', (elements) =>
elements.some((el) => el.textContent.includes(element))
);
} catch (error) {
console.log(error);
}
})
await browser.close();
})();
}
);
But all I get is
(node:6701) UnhandledPromiseRejectionWarning: Error: Protocol error (Runtime.evaluate): Target closed.
at /var/www/v4/tests/utils/node_modules/puppeteer/lib/cjs/puppeteer/common/Connection.js:208:63
at new Promise (<anonymous>)
at CDPSession.send (/var/www/v4/tests/utils/node_modules/puppeteer/lib/cjs/puppeteer/common/Connection.js:207:16)
at ExecutionContext._evaluateInternal (/var/www/v4/tests/utils/node_modules/puppeteer/lib/cjs/puppeteer/common/ExecutionContext.js:162:18)
at ExecutionContext.evaluateHandle (/var/www/v4/tests/utils/node_modules/puppeteer/lib/cjs/puppeteer/common/ExecutionContext.js:151:21)
at /var/www/v4/tests/utils/node_modules/puppeteer/lib/cjs/puppeteer/common/DOMWorld.js:101:44
at processTicksAndRejections (internal/process/task_queues.js:93:5)
(node:6701) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict`
Does anyone knows how can I make it work? Thanks
Upvotes: 0
Views: 1472
Reputation: 179
It looks like you are closing the browser before your values.forEach
method finishes running. Making it Promise
and waiting for it to resolve might solve the problem.
Upvotes: 1
Reputation: 13782
for...of
loop would be better for this)..evaluate()
would be more fast.innerText
can be more readable than textContent
.You can try something like this:
const puppeteer = require('puppeteer');
const values = ['domain', 'examples', 'documents', 'foo bar'];
(async () => {
const browser = await puppeteer.launch();
const [page] = await browser.pages();
await page.goto('https://example.com');
const matches = await page.evaluate((strings) => {
const text = document.body.innerText;
return strings.filter(string => text.includes(string));
}, values);
console.log(matches);
await browser.close();
})();
Upvotes: 0