Reputation: 942
I've been using Puppeteer to scrape some websites, and it works well when the element I need is in the DOM; however I can't get it to work when the element is loaded via Javascript. E.g. please see my code below. More specifically, the page.waitForSelector always triggers a timeout error. I've tried a page.screenshot and the resulting image does show a fully loaded page, which contains this .evTextFont element.
How can I modify this code to successfully retrieve the .evTextFont element?
I've tried both Puppeteer versions 1.11 and 1.17, but am getting the same problem for both
Thanks a lot
Adapted from here
const puppeteer = require('puppeteer');
const URL = 'https://www.paintbar.com.au/events-1/moments-in-moonlight';
puppeteer.launch({ headless: true, args: ['--no-sandbox', '--disable-setuid-sandbox'] }).then(async browser => {
const page = await browser.newPage();
await page.setViewport({width: 1200, height: 600})
await page.goto(URL, {waitUntil: 'networkidle0'});
await page.waitForSelector('.evTextFont');
await page.addScriptTag({url: 'https://code.jquery.com/jquery-3.2.1.min.js'});
// await page.screenshot({ path: './image.jpg', type: 'jpeg' });
const result = await page.evaluate(() => {
try {
var data = [];
$('.evTextFont').each(function() {
const title = $(this).text();
data.push({
'title' : title,
});
});
return data;
} catch(err) {
console.log(err.toString());
}
});
await browser.close();
for(var i = 0; i < result.length; i++) {
console.log('Data: ' + result[i].title);
}
process.exit();
}).catch(function(error) {
console.error(error);
process.exit();
});
Upvotes: 2
Views: 659
Reputation: 16838
It happens because the event you're looking for is shown inside of an iframe
element, from another site, so you need to find that iframe first and then do operation on it.
await page.goto(URL, {waitUntil: 'networkidle0'});
// Looking for the iframe with the event
const frame = (await page.frames()).find(f => f.url().includes("events.wix.com"));
// Then do work as before, but on that frame
await frame.waitForSelector('.evTextFont');
await frame.addScriptTag({url: 'https://code.jquery.com/jquery-3.2.1.min.js'});
const result = await frame.evaluate(() => {...})
Upvotes: 1