Welcome folks today in this blog post we will be uploading screenshot of webpage & upload to cloudinary in node.js & express using puppeteer library in javascript. All the full source code of the application is shown below.
Get Started
In order to get started you need to create the new node.js project using the below command as shown below
npm init -y
Now we need to create the dependencies of the node.js project as shown below
npm i puppeteer
npm i express
npm i ejs
npm i cloudinary
After installing all these dependencies you need to create the index.js
file in the root directory and copy paste the following code
index.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
const express = require("express"); const bodyparser = require('body-parser') const app = express(); app.use(bodyparser.urlencoded({extended:false})) app.use(bodyparser.json()) app.set('view engine','ejs') const puppeteer = require('puppeteer'); const cloudinary = require('cloudinary').v2; cloudinary.config({ cloud_name:"", api_key:"", api_secret:"" }); app.listen(5000,() => { console.log("App is listening on port 5000") }) |
As you can see we are importing the express library and starting the app at port number 5000. And also we are setting the ejs
view engine using the set()
method and also we are importing the puppeteer library and then we are also including the bodyparser middleware and then we are setting the cloudinary
config information which is the cloud_name
,api_key and api_secret
. We can get this information from the cloudinary
dashboard as shown below
And as you can see from the figure above you can get the api key , secret key and cloudname simply copy this and replace it inside the code shown above.
Now we will be writing the simple get
request to the /
route when we open the homepage we will be loading the index.ejs
file as shown below
1 2 3 |
app.get('/',(req,res) => { res.render('index',{result:''}) }) |
And for this we need to make the views
folder and inside it make the index.ejs
file as shown below
views/index.ejs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <form action="/upload" method="post"> <input type="text" name="url" placeholder="Enter the URL" required/> <input type="submit" value="Upload Screenshot to Cloudinary"> </form> </body> </html> |
In this above section of code we have the html5 form
inside that we have the input
field in which we will be writing the url
of the webpage to take screenshot and upload to cloudinary. And then we have the button to submit the html5 form.
Now we will be writing the post
request to the /upload
route inside the index.js
file. Just copy paste the below code
index.js
1 2 3 4 5 6 7 8 9 10 |
// Create an express route app.post("/upload", (req, res) => { console.log(req.body.url) takeScreenshot(req.body.url) .then((screenshot) => uploadScreenshot(screenshot)) .then((result) => { console.log(result) res.render('index',{result:result}) }); }); |
As you can see we are getting the url
submitted by the user and then we are calling the takeScreenshot()
custom function and inside this we are passing the url
of the webpage to take screenshot. And then it returns the promise it contains the screenshot image taken by the puppeteer and then we are calling another custom function which is called uploadScreenshot() which takes the screenshot image to be uploaded to cloudinary and then it also returns the promise inside that we are re-rendering the index.ejs
file and we are passing the result
to the index.ejs
file.
Taking Screenshot of URL Using Puppeteer
Now we will be writing the function to take the screenshot of the webpage using the puppeteer library as shown below
index.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
async function takeScreenshot(embedUrl) { const browser = await puppeteer.launch({ defaultViewport: { width: 800, height: 800, isLandscape: true } }); const page = await browser.newPage(); await page.goto( embedUrl, { waitUntil: 'networkidle2' } ); const screenshot = await page.screenshot({ omitBackground: true, encoding: 'binary' }); await browser.close(); return screenshot; } |
As you can see in the above code we are opening the passed url using the puppeteer library inside the browser and then we are using the screenshot()
method of the puppeteer library to take picture of webpage and then returning the screenshot of the webpage from this function.
Uploading Screenshot to Cloudinary
Now we will be uploading the screenshot to the cloudinary as shown below
index.js
1 2 3 4 5 6 7 8 9 |
function uploadScreenshot(screenshot) { return new Promise((resolve, reject) => { const uploadOptions = {}; cloudinary.uploader.upload_stream(uploadOptions, (error, result) => { if (error) reject(error) else resolve(result); }).end(screenshot); }); } |
As you can see in the above code we are returning the promise inside that we are using the upload_stream()
method to take the upload options and then we are passing the screenshot of the webpage to the end()
method. This function will return the information of the uploaded screenshot to cloudinary as shown below
Displaying Screenshot in Browser
Now we will be displaying the image uploaded to cloudinary in the browser using the secure_url property which is returned from the cloudinary api as shown below
index.ejs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <form action="/upload" method="post"> <input type="text" name="url" placeholder="Enter the URL" required/> <input type="submit" value="Upload Screenshot to Cloudinary"> </form> <%if(result){%> <img src="<%=result.secure_url%>"/> <%}%> </body> </html> |
Now if you execute
the node.js app in the command line as shown below
node index.js
Wrapping the blog post this is the full source code of the index.js
file as shown below
index.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
const express = require("express"); const bodyparser = require('body-parser') const app = express(); app.use(bodyparser.urlencoded({extended:false})) app.use(bodyparser.json()) app.set('view engine','ejs') const puppeteer = require('puppeteer'); const cloudinary = require('cloudinary').v2; cloudinary.config({ cloud_name:"codingshiksha", api_key:"316965143126875", api_secret:"hMboXUIPnK7ry8K3t3Q_NWIJzCw" }); app.get('/',(req,res) => { res.render('index',{result:''}) }) // Create an express route app.post("/upload", (req, res) => { console.log(req.body.url) takeScreenshot(req.body.url) .then((screenshot) => uploadScreenshot(screenshot)) .then((result) => { console.log(result) res.render('index',{result:result}) }); }); app.listen(5000,() => { console.log("App is listening on port 5000") }) // See https://bitsofco.de/using-a-headless-browser-to-capture-page-screenshots async function takeScreenshot(embedUrl) { const browser = await puppeteer.launch({ defaultViewport: { width: 800, height: 800, isLandscape: true } }); const page = await browser.newPage(); await page.goto( embedUrl, { waitUntil: 'networkidle2' } ); const screenshot = await page.screenshot({ omitBackground: true, encoding: 'binary' }); await browser.close(); return screenshot; } function uploadScreenshot(screenshot) { return new Promise((resolve, reject) => { const uploadOptions = {}; cloudinary.uploader.upload_stream(uploadOptions, (error, result) => { if (error) reject(error) else resolve(result); }).end(screenshot); }); } |