How to download and upload files in Puppeteer
Tags: puppeteer, node, automation
Published: 2024-04-02 12:50:14

---
title: How to download and upload files in Puppeteer
published: true
date: 2023-11-21 23:00:00 UTC
tags: puppeteer, nodejs, automation
canonical_url: https://blog.apify.com/how-to-download-and-upload-files-in-puppeteer/
---

 **Hey, we're** [**Apify**](https://apify.com/) **, the only full-stack web scraping and automation library. Check out some of our easy to use** [**web scraping code templates**](https://apify.com/templates) **if you want to get started on building your own Puppeteer scrapers.**

[Puppeteer](https://pptr.dev/) is a Node.js library that allows you to interact with `headless` and `headful` Chrome browsers. It enables you to perform lots of tasks, such as navigating web pages, taking [screenshots, generating PDFs](https://blog.apify.com/puppeteer-screenshot-pdf-how-to/), and handling filesboth downloads and uploads. Puppeteer essentially allows you to automate tasks that would typically require manual intervention in a web browser.

![How to download and upload files in Puppeteer](https://blog.apify.com/content/images/2023/11/download-and-upload-files-in-Puppeteer-1.png)

### **Why handle file downloads and uploads?**

File downloads and uploads are common activities when automating web interactions. Whether you're scraping data from websites, testing file upload functionality, or automating document retrieval, Puppeteer's ability to download and upload files makes it an invaluable tool.

## **Setting up Puppeteer**

To set up Puppeteer, you need to have [Node.js](https://nodejs.org/) installed on your computer. If you haven't installed it yet, you can follow this [guide](https://blog.apify.com/how-to-install-nodejs/) for a step-by-step procedure on how to do it.

Once Node.js is installed, it will also install `npm` for you. You can verify this by opening your command prompt (CMD) or your terminal and using this command:

```
node -v && npm -v
```

The output will look like the image below:

![terminal screenshot, showing node and npm version installed on a computer](https://blog.apify.com/content/images/2023/11/Screenshot-2023-10-06-at-11.01.12.png)

_Node and NPM version installed on a computer_

After that, you can go to your desired location on your computer to create a folder (either desktop or documents) for your project. You'll initialize a new Node.js project in the folder you created using `npm init`, which will bring up some prompts. Follow through with the prompts, and that will set you up.

![Installing Node.js](https://blog.apify.com/content/images/2023/11/Screenshot-2023-10-06-at-11.37.09.png)

_Installing Node.js_

In the image above, a folder called `puppeteer-download-upload` is created. The `cd puppeteer-download-upload` command is used to change your directory into the folder, and the `npm init` command is used to initialize Node.js into the folder. The prompts came up and were filled in accordingly.

This is so you can run `Node.js` operations within the project.

The next step is for you to install Puppeteer.

In the same project folder, open your terminal, change your directory, and run this command:

```
npm install puppeteer
```

> 📒_Note: Anytime you're working on a new Puppeteer project, you'll have to perform these operations:_  
> 1. Create a new project folder  
> 2. Initialize Node into the folder  
> 3. Install Puppeteer

With Puppeteer successfully installed, you're ready to start automating.

## **Performing download operations with Puppeteer**

To perform a download operation with Puppeteer, you'll need a method to trigger the download action, specify the path at which you want the file to be downloaded, and finally take the download action. After deciding on the method, specify the download path and then trigger the download action by navigating to the page or link and clicking the download link.

There are various methods and approaches you can use to perform download operations with Puppeteer. Here are three of them:

1. Intercepting network requests using `page.setRequestInterception(true)`. You can use this to detect a request for a file download based on the content. If you want to learn more about this method, you should read about [request interception](https://pptr.dev/api/puppeteer.page.setrequestinterception) in the Puppeteer documentation.

```
await page.setRequestInterception(true);page.on('request', (interceptedRequest) => { // Check the URL or content type to detect a download request if (interceptedRequest.url().endsWith('.pdf')) || interceptedRequest.url().endsWith('.jpg') { // Handle the download here... } interceptedRequest.continue();});// If the file download doesn't start right away, click a button to trigger itawait page.click('#downloadButton')
```

1. Browser Contexts and `setDownloadBehavior`. This is a more direct way to handle downloads using Puppeteer. In this case, when the download is triggered, the file will automatically be downloaded to the specified directory or path. The previous version used the `page._client` private API, but it was deprecated. Instead, you should create your own [CDP sessions](https://pptr.dev/api/puppeteer.cdpsession) for access to the [Chrome dev protocol](https://chromedevtools.github.io/devtools-protocol/tot/Page/#method-setDownloadBehavior) directly, like so:

```
const browser = await puppeteer.launch({ headless: false });const page = await browser.newPage()const client = await page.target().createCDPSession()await client.send('Page.setDownloadBehavior', { behavior: 'allow', downloadPath: '/path/to/save/downloads' });// If the file download doesn't start right away, click a button to trigger itawait page.click('#downloadButton')
```

Each of the methods listed above is suited to different download scenarios. Just choose the one that best fits the project or task you're working on.

### **Tips for handling errors**

1. Handle timeout within your code to give more time for the download operation to be completed.

2. To ensure the file is downloaded successfully, you can use the `[page.waitForResponse](<https://pptr.dev/api/puppeteer.page.waitforresponse>)` and `targetcreated` conditions.

3. You can also check the specified directory manually to ensure the file exists and is of the expected size.

## **Uploading files with Puppeteer**

To perform an upload operation with Puppeteer, you'll need a method that lets you perform the file selection option, specify the path at which you want the file to be selected from, and then finally take the upload action.

You can use the `elementHandle.uploadFile(...path)` method that allows you to upload a file by providing the path, or you can use the `fileChooser` method.

The `FileChooser` works when the file chooser has a dialog while `elementHadle.uploadFile` works directly with the file input element. The method you use depends on the scenario you're working with. If the webpage has a custom button or hides the original file input, `FileChooser` is advisable. If you're dealing with a standard file input, `elementHandle.uploadFile` is a better option.

```
//the code sample of FileChooserconst [fileChooser] = await Promise.all([page.waitForFileChooser(), page.click('#customUploadButton')]);await fileChooser.accept(['/path/file.jpg']);
```

* * *

```
//code sample for ElementHandle.uploadFileconst UploadElement = await page.$('input[type="file"]');await uploadElement.uploadFile('/path/file.jpg');
```

After deciding on the method, specify the path and then trigger the upload action (navigate to the page or link, click the upload button, and submit).

### **Best practices for secure file uploads**

1. Check the file type required for upload and make sure you're uploading the correct file type.

2. Check and verify the file input and button selectors.

3. Monitor and handle network requests accordingly.

## **Examples of using upload and download**

In this section, you'll be trying out the upload and download options available in Puppeteer.

### **1. Automating a file upload with Puppeteer**

In the code below, you'll set up your Puppeteer project as explained earlier, create a new file called `upload.js`, import Puppeteer, then add a `test pdf file` in the root folder for the purpose of the example.

```
import puppeteer from "puppeteer";// function to handle timeout for every action to be completedfunction delay(time) { return new Promise(resolve => setTimeout(resolve, time));} const browser = await puppeteer.launch({ headless: false }); const page = await browser.newPage(); await page.goto('<https://easyupload.io/>'); await page.waitForSelector('input[type=file]'); const inputUploadHandle = await page.$('input[type=file]'); // path to the file you want to upload await inputUploadHandle.uploadFile('./testdoc.pdf'); await page.click('#upload'); // Introduce a timeout if necessary (in case of internet speed) await delay(20000); // Wait for a success message. await page.waitForSelector('.upload-success'); await browser.close();
```

### **2. Automating the download of the file you uploaded earlier**

In the previous example, you uploaded a file to `[easyupload.io](<http://easyupload.io>)`, after which you were given a download link. Copy the download link to the file, and replace it with the URL in `page.goto('...')`. Also, create a folder named `downloads`. This is where your file will be downloaded.

```
import puppeteer from 'puppeteer'import * as fs from 'fs';//function to handle timeout function delay(time) { return new Promise(resolve => setTimeout(resolve, time)); } const browser = await puppeteer.launch({ headless: false }); const page = await browser.newPage(); // Set download behavior const client = await page.target().createCDPSession() await client.send('Page.setDownloadBehavior', { behavior: 'allow', // the download path can be set to a folder in your project root downloadPath: './downloads' }); // Navigate to the download page. (change the download URL) await page.goto('<https://easyupload.io/x2na1r>'); // Download the file. await page.click('#hd1'); // Wait for the download to complete. Adjust this based on your network speed. await delay(10000);; //check the download folder to know if the downloaded file exists there if (fs.existsSync('./downloads/testdoc.pdf')) { console.log('file downloaded successfully!'); } else { console.log('Download failed.'); } await browser.close();
```

### **3. Another code sample for upload and download actions with Puppeteer**

```
import puppeteer from 'puppeteer'//function to handle timeoutfunction delay(time) { return new Promise(resolve => setTimeout(resolve, time));} const browser = await puppeteer.launch({ headless: false }); const page = await browser.newPage(); const client = await page.target().createCDPSession(); await client.send('Page.setDownloadBehavior', { behavior: 'allow', downloadPath: './downloads' }); await page.goto('<https://imgur.com/upload>'); const uploadSelector = '#file-input'; await page.waitForSelector(uploadSelector); const inputUploadHandle = await page.$(uploadSelector); await inputUploadHandle.uploadFile('./cap.jpeg'); //wait for the upload to be completed await delay(10000); // initiate the download process and click the download button const downloadLinkSelector = '.upload-download'; await page.waitForSelector(downloadLinkSelector); await page.click(downloadLinkSelector); //wait for the file download to await delay(10000); await browser.close();
```

You can find some more examples of [downloading files in Puppeteer](https://docs.apify.com/academy/puppeteer-playwright/common-use-cases/downloading-files) and [submitting a form with an attachment](https://docs.apify.com/academy/puppeteer-playwright/common-use-cases/submitting-a-form-with-a-file-attachment) in the Apify docs.

### **GitHub gists**

You can explore all the sample code in this tutorial in the GitHub gists below.

- [Upload](https://gist.github.com/CodeLeom/bd4c7c17a0749044f7a1a9b606c3e5ae)

- [Download](https://gist.github.com/CodeLeom/6f3055951fca57d36819feb5143187cf)

- [Upload and Download](https://gist.github.com/CodeLeom/c5ce35fec15359786045208ddc24a4e0)

>💻[How to scrape the web with Puppeteer in 2023](https://blog.apify.com/puppeteer-web-scraping-tutorial/)