Reputation: 971
I am trying to return the full css response and save to the file but it is returning some weird object: here is my code:
const puppeteer = require('puppeteer'),
fs = require('fs');
const JSON = require('circular-json');
function run (url) {
return new Promise(async (resolve, reject) => {
try {
const browser = await puppeteer.launch();
const page = await browser.newPage();
var allCSS = [];
let css = await page.on('response', async response => {
if(response.request().resourceType() === 'stylesheet') {
return JSON.stringify(response.text());
}
});
let body = await page.evaluate(() => {
return items = document.getElementsByTagName('#Id');
})
await page.goto(url);
await browser.close();
return resolve({body: body, css: css});
} catch (e) {
return reject(e);
}
})
}
run("http://localhost/gogo/test.html")
.then((css)=>{
//var css = JSON.stringify(body.css);
fs.writeFile('data/css/first.css', css, 'utf8', function(){
console.log("CSS DONE")
});
}).catch(console.error);
Now the issue is that it is returning an object with all the stuff with like events...
, _connection...
and its a huge json file now? how do i get only the stylesheet
Upvotes: 0
Views: 1722
Reputation: 7855
Have you considered something like this?
const promise = new Promise(async (resolve, reject) => {
const css = [];
page.on('response', async response => {
if (response.request().resourceType() === 'stylesheet') {
css.push(await response.text());
}
});
page.on('load', () => resolve(css)); // Ensure the page is loaded before resolving
});
And then just check your promise:
(async () => {
const result = await promise;
console.log(result);
})();
This approach differs from yours in that you can continue to stay in the page/session without closing the browser. This might be helpful in cases where you may want to perform additional checks on the page.
Upvotes: 0
Reputation: 11132
response.text()
returns a Promise, not the actual text itself. You would need to await the result of this promise, something like this:
return JSON.stringify(await response.text());
However, I believe that there's another issue. As far as I am aware, you cannot await an event; you can only create the callback for an event. So, this code is inherently incorrect:
let css = await page.on(...
Fixing this should not be too difficult. What you need to do is register the event callback similar to how you have been doing so:
page.on('response', async response => {
if(response.request().resourceType() === 'stylesheet') {
But then, inside the callback, you should resolve the promise:
resolve(JSON.stringify(await response.text()));
Alternately, if you want to capture more than one stylesheet, you'd need to add the CSS to your list. Then, after you reach a certain threshold (time, number of stylesheets captured, etc.), you resolve the promise with that list of all the CSS.
Final code (for only one stylesheet) should look something like this:
try {
const browser = await puppeteer.launch();
const page = await browser.newPage();
page.on('response', async response => { // don't await anything on this line
if(response.request().resourceType() === 'stylesheet') {
resolve(JSON.stringify(await response.text())); // await and resolve here
}
});
await page.goto(url);
await browser.close();
// don't resolve here
} catch (e) {
return reject(e);
}
Upvotes: 1