---
title: "Using Cheerio NPM for Web Scraping"
slug: cheerio-npm-web-scraping
date: 2023-08-02T08:17:44+00:00
modified: 2025-09-16T08:50:13+00:00
permalink: https://brightdata.com/blog/how-tos/cheerio-npm-web-scraping
type: blog
---

[ Blog ](https://brightdata.com/blog "Blog") / [How Tos](https://brightdata.com/blog/how-tos)







 [How Tos](https://brightdata.com/blog/how-tos)

# Using Cheerio NPM for Web Scraping

Learn how to scrape dynamic and static websites using Cheerio NPM in this step by step guide

 8 min read





 [ ](https://brightdata.com/blog/authors/aniket-bhattacharyea)

 [Aniket Bhattacharyea

 ](https://brightdata.com/blog/authors/aniket-bhattacharyea)





 ![Cheerio NPM web scraping](https://media.brightdata.com/2023/08/Cheerio-scraping.svg)





Node.js has emerged as a powerful option for building web scrapers, offering convenience for both client-side and server-side developments. Its extensive catalog of libraries makes web scraping with Node.js a breeze. In this article, cheerio will be spotlighted, and its capabilities will be explored for efficient web scraping.

Cheerio is a fast and flexible library for parsing and manipulating HTML and XML documents. It implements a subset of jQuery features, which means anyone familiar with jQuery will find themselves at home with the syntax of cheerio. Under the hood, cheerio uses the `parse5` and, optionally, the `htmlparser2` libraries for parsing HTML and XML documents.

In this article, you’ll create a project that uses cheerio and learn how to [scrape data from dynamic websites](/blog/how-tos/scrape-dynamic-websites-python) and static web pages.

## <a></a>Web Scraping with cheerio

Before you begin this tutorial, make sure you have Node.js installed on your system. If you don’t have it already, you can install it using the [official documentation](https://nodejs.org/en/download).

Once you’ve installed Node.js, create a directory called `cheerio-demo` and `cd` into it:

  ```
mkdir cheerio-demo u0026u0026 cd cheerio-demon
```

Then initialize an npm project in the directory:

  ```
npm init -yn
```

Install the [cheerio](https://www.npmjs.com/package/cheerio) and [Axios](https://www.npmjs.com/package/axios) packages:

  ```
npm install cheerio axiosn
```

Create a file called `index.js`, which is where you’ll be writing the code for this tutorial. Then open this file in your favorite editor to get started.

The first thing you need to do is to import the required modules:

  ```
const axios = require(u0022axiosu0022);nconst cheerio = require(u0022cheeriou0022);n
```

In this tutorial, you’ll scrape the [Books to Scrape page](https://books.toscrape.com/), a public sandbox for testing web scrapers. First you’ll use Axios to make a `GET` request to the web page with the following code:

  ```
axios.get(u0022https://books.toscrape.com/u0022).then((response) =u003e {n    n});n
```

The `response` object in the callback contains the HTML code of the web page in the `data` property. This HTML needs to be passed to the `load` function of the `cheerio` module. This function returns an instance of [`CheerioAPI`](https://cheerio.js.org/docs/api/interfaces/CheerioAPI), which will be used to access and manipulate the DOM for the rest of the code. Note that the `CheerioAPI` instance is stored in a variable named `$`, which is a nod to the jQuery syntax:

  ```
axios.get(u0022https://books.toscrape.com/u0022).then((response) =u003e {n    const $ = cheerio.load(response.data);n});n
```

### <a></a>Finding Elements

cheerio supports using CSS and XPath selectors for selecting elements from the page. If you’ve used jQuery, you’ll find the syntax familiar—pass the CSS selector to the `$()` function. Use this syntax to find and extract information on the first page of the Books to Scrape website.

Visit <https://books.toscrape.com/> and open up the Developer Console. Search the **Inspect Element** tab, where you’ll learn more about the HTML structure of the page. In this case, you can see that all the information about the books is contained in `article` tags with the class `product-pod`:

To select the books, you need to use the `article.product_pod` CSS selector like this:

  ```
$(u0022article.product_podu0022);n
```

This function returns a list of all the elements that match the selector. You can use the `each` method to iterate over the list:

  ```
$(u0022article.product_podu0022).each( (i, element) =u003e {nn});n
```

Inside the loop, you can use the `element` variable to extract the data.

Try to extract the title of the books on the first page. Going back to the **Inspect Element** console, you can see how the titles are stored:

You see that you need to find an `h3`, which is a child of the `element` variable. Inside the `h3`, there is an `a` element that holds the book’s title. You can use the [`find`](https://cheerio.js.org/docs/api/classes/Cheerio#find) method with a CSS selector to find the children of an element, but initially, you need to pass `element` through `$` to convert it into an instance of `Cheerio`:

  ```
$(u0022article.product_podu0022).each( (i, element) =u003e {n    const titleH3 = $(element).find(u0022h3u0022);nn});n
```

Now, you can find the `a` inside `titleH3`:

  ```
$(u0022article.product_podu0022).each( (i, element) =u003e {n    const titleH3 = $(element).find(u0022h3u0022);n    const title = titleH3.find(u0022au0022);n});n
```

> **Note:** `titleH3` is already an instance of `Cheerio`, so you don’t need to pass it through `$`.

### <a></a>Extracting Text

Once you’ve selected an element, you can get the text of that element using the [`text`](https://cheerio.js.org/docs/api/classes/Cheerio#text) method.

Modify the previous example to extract the book’s title by calling the `text` method on the result of the `find` method:

  ```
$(u0022article.product_podu0022).each( (i, element) =u003e {n    const titleH3 = $(element).find(u0022h3u0022);n    const title = titleH3.find(u0022au0022).text();nn    console.log(title);n});n
```

The complete code should look like this:

  ```
const axios = require(u0022axiosu0022);nconst cheerio = require(u0022cheeriou0022);nnaxios.get(u0022https://books.toscrape.com/u0022).then((response) =u003e {n    const $ = cheerio.load(response.data);nn    $(u0022article.product_podu0022).each( (i, element) =u003e {n        const titleH3 = $(element).find(u0022h3u0022);n        const title = titleH3.find(u0022au0022).text();nn        console.log(title);n    });n});n
```

Run the code with `node index.js`, and you should see the following output:

  ```
A Light in the ...nTipping the VelvetnSoumissionnSharp ObjectsnSapiens: A Brief History ...nThe Requiem RednThe Dirty Little Secrets ...nThe Coming Woman: A ...nThe Boys in the ...nThe Black MarianStarving Hearts (Triangular Trade ...nShakespeare's SonnetsnSet Me FreenScott Pilgrim's Precious Little ...nRip it Up and ...nOur Band Could Be ...nOlionMesaerion: The Best Science ...nLibertarianism for BeginnersnIt's Only the Himalayasn
```

### <a></a>Navigating the DOM: Finding Children and Siblings

Once you’ve extracted the titles, it’s time to extract the price and availability of each book. The **Inspect Element** reveals that both the price and availability are stored in a `div` with the class `product_price`. You can select this `div` with the `.product_price` CSS selector, but since you’ve already covered CSS selectors, the following will discuss another way to do this:

> **Note:** The `div` is a sibling of the `titleH3` you selected previously. By calling the [`next`](https://cheerio.js.org/docs/api/classes/Cheerio#next) method of `titleH3`, you can select the next sibling:

  ```
const priceDiv = titleH3.next();n
```

You’ve already seen that you can use the `find` method to find the children of an element based on CSS selectors. You can also select all the children with the [`children`](https://cheerio.js.org/docs/api/classes/Cheerio#children) method and then use the [`eq`](https://cheerio.js.org/docs/api/classes/Cheerio#eq) method to select a particular child. This is equivalent to the `nth-child` CSS selector.

In this case, the price is the first child of `priceDiv`, and the availability is the second child of `priceDiv`. This means you can select them with `priceDiv.children().eq(0)` and `priceDiv.children().eq(1)`, respectively. Do that and print the price and availability:

  ```
$(u0022article.product_podu0022).each( (i, element) =u003e {n    const titleH3 = $(element).find(u0022h3u0022);n    const title = titleH3.find(u0022au0022).text();nnn    const priceDiv = titleH3.next();n    const price = priceDiv.children().eq(0).text().trim();n    const availability = priceDiv.children().eq(1).text().trim();n    console.log(title, price, availability);n});n
```

Now, running the code shows the following output:

  ```
A Light in the ... Â£51.77 In stocknTipping the Velvet Â£53.74 In stocknSoumission Â£50.10 In stocknSharp Objects Â£47.82 In stocknSapiens: A Brief History ... Â£54.23 In stocknThe Requiem Red Â£22.65 In stocknThe Dirty Little Secrets ... Â£33.34 In stocknThe Coming Woman: A ... Â£17.93 In stocknThe Boys in the ... Â£22.60 In stocknThe Black Maria Â£52.15 In stocknStarving Hearts (Triangular Trade ... Â£13.99 In stocknShakespeare's Sonnets Â£20.66 In stocknSet Me Free Â£17.46 In stocknScott Pilgrim's Precious Little ... Â£52.29 In stocknRip it Up and ... Â£35.02 In stocknOur Band Could Be ... Â£57.25 In stocknOlio Â£23.88 In stocknMesaerion: The Best Science ... Â£37.59 In stocknLibertarianism for Beginners Â£51.33 In stocknIt's Only the Himalayas Â£45.17 In stockn
```

### <a></a>Accessing Attributes

So far, you’ve navigated the DOM and extracted texts from the elements. It’s also possible to extract attributes from an element using cheerio, which is what you’ll do in this section. Here, you’ll extract the rating of books by reading the class list of elements.

The rating of the books has an interesting structure. The ratings are contained in a `p` tag. Each `p` tag has exactly five stars, but the stars are colored using CSS based on the class name of the `p` element. For example, in a `p` with class `star-rating.Four`, the first four stars are colored yellow, denoting a four-star rating:

To extract the rating of a book, you need to extract the class names of the `p` element. The first step is to find the paragraph containing the rating:

  ```
const ratingP = $(element).find(u0022p.star-ratingu0022);n
```

By passing the attribute name to the [`attr`](https://cheerio.js.org/docs/api/classes/Cheerio#attr) method, you can read the attributes of an element. In this case, you need to read the class list, which is demonstrated in the following code:

  ```
const starRating = ratingP.attr('class');n
```

The class list is in the following form: `star-rating X`, where `X` is one of `One`, `Two`, `Three`, `Four`, and `Five`. This means you need to split the class list on space and take the second element. The following code does that and converts the textual rating into a numerical rating:

  ```
const rating = { One: 1, Two: 2, Three: 3, Four: 4, Five: 5 }[starRating.split(u0022 u0022)[1]];n
```

If you put everything together, your code will look like this:

  ```
$(u0022article.product_podu0022).each( (i, element) =u003e {n    const titleH3 = $(element).find(u0022h3u0022);n    const title = titleH3.find(u0022au0022).text();nnn    const priceDiv = titleH3.next();n    const price = priceDiv.children().eq(0).text().trim();n    const availability = priceDiv.children().eq(1).text().trim();nn    const ratingP = $(element).find(u0022p.star-ratingu0022);n    const starRating = ratingP.attr('class');n    const rating = { One: 1, Two: 2, Three: 3, Four: 4, Five: 5 }[starRating.split(u0022 u0022)[1]];nn    console.log(title, price, availability, rating);n});n
```

The output looks like this:

  ```
A Light in the ... Â£51.77 In stock 3nTipping the Velvet Â£53.74 In stock 1nSoumission Â£50.10 In stock 1nSharp Objects Â£47.82 In stock 4nSapiens: A Brief History ... Â£54.23 In stock 5nThe Requiem Red Â£22.65 In stock 1nThe Dirty Little Secrets ... Â£33.34 In stock 4nThe Coming Woman: A ... Â£17.93 In stock 3nThe Boys in the ... Â£22.60 In stock 4nThe Black Maria Â£52.15 In stock 1nStarving Hearts (Triangular Trade ... Â£13.99 In stock 2nShakespeare's Sonnets Â£20.66 In stock 4nSet Me Free Â£17.46 In stock 5nScott Pilgrim's Precious Little ... Â£52.29 In stock 5nRip it Up and ... Â£35.02 In stock 5nOur Band Could Be ... Â£57.25 In stock 3nOlio Â£23.88 In stock 1nMesaerion: The Best Science ... Â£37.59 In stock 1nLibertarianism for Beginners Â£51.33 In stock 2nIt's Only the Himalayas Â£45.17 In stock 2n
```

### <a></a>Saving the Data

After scraping the data from the web page, you’d generally want to save it. There are several ways you can do this, such as saving to a file, saving to a database, or feeding it to a data processing pipeline. In this section, you’ll learn the simplest of all—saving data in a CSV file.

To do so, install the `node-csv` package:

  ```
npm install csvn
```

In `index.js`, import the `fs` and `csv-stringify` modules:

  ```
const fs = require(u0022fsu0022);nconst { stringify } = require(u0022csv-stringifyu0022);n
```

To write a local file, you need to create a `WriteStream`:

  ```
const filename = u0022scraped_data.csvu0022;nconst writableStream = fs.createWriteStream(filename);n
```

Declare the column names, which are added to the CSV file as headers:

  ```
const columns = [n  u0022titleu0022,n  u0022ratingu0022,n  u0022priceu0022,n  u0022availabilityu0022n];n
```

Create a stringifier with the column names:

  ```
const stringifier = stringify({ header: true, columns: columns });n
```

Inside the `each` function, you’ll use `stringifier` to write the data:

  ```
$(u0022article.product_podu0022).each( (i, element) =u003e {n    ...nn    const data = { title, rating, price, availability };n    stringifier.write(data);nn});n
```

Finally, outside the `each` function, you need to write the contents of `stringifier` into the `writableStream` variable:

  ```
stringifier.pipe(writableStream);n
```

At this point, your code should look like this:

  ```
const axios = require(u0022axiosu0022);nconst cheerio = require(u0022cheeriou0022);nconst fs = require(u0022fsu0022);nconst { stringify } = require(u0022csv-stringifyu0022);nnconst filename = u0022scraped_data.csvu0022;nconst writableStream = fs.createWriteStream(filename);nnconst columns = [n  u0022titleu0022,n  u0022ratingu0022,n  u0022priceu0022,n  u0022availabilityu0022n];nconst stringifier = stringify({ header: true, columns: columns });nnaxios.get(u0022https://books.toscrape.com/u0022).then((response) =u003e {n    const $ = cheerio.load(response.data);nn    $(u0022article.product_podu0022).each( (i, element) =u003e {n        const titleH3 = $(element).find(u0022h3u0022);n        const title = titleH3.find(u0022au0022).text();n    n        const priceDiv = titleH3.next();n        const price = priceDiv.children().eq(0).text().trim();n        const availability = priceDiv.children().eq(1).text().trim();n        const ratingP = $(element).find(u0022p.star-ratingu0022);n        const starRating = ratingP.attr('class');n        const rating = { One: 1, Two: 2, Three: 3, Four: 4, Five: 5 }[starRating.split(u0022 u0022)[1]];nn        console.log(title, price, availability, rating);nn        const data = { title, rating, price, availability };n        stringifier.write(data);nn    });nn    stringifier.pipe(writableStream);nn});n
```

Run the code, and it should create a `scraped_data.csv` file with the scraped data inside:

  ```
title,rating,price,availabilitynA Light in the ...,3,Â£51.77,In stocknTipping the Velvet,1,Â£53.74,In stocknSoumission,1,Â£50.10,In stocknSharp Objects,4,Â£47.82,In stocknSapiens: A Brief History ...,5,Â£54.23,In stocknThe Requiem Red,1,Â£22.65,In stocknThe Dirty Little Secrets ...,4,Â£33.34,In stocknThe Coming Woman: A ...,3,Â£17.93,In stocknThe Boys in the ...,4,Â£22.60,In stocknThe Black Maria,1,Â£52.15,In stocknStarving Hearts (Triangular Trade ...,2,Â£13.99,In stocknShakespeare's Sonnets,4,Â£20.66,In stocknSet Me Free,5,Â£17.46,In stocknScott Pilgrim's Precious Little ...,5,Â£52.29,In stocknRip it Up and ...,5,Â£35.02,In stocknOur Band Could Be ...,3,Â£57.25,In stocknOlio,1,Â£23.88,In stocknMesaerion: The Best Science ...,1,Â£37.59,In stocknLibertarianism for Beginners,2,Â£51.33,In stocknIt's Only the Himalayas,2,Â£45.17,In stockn
```

## <a></a>Conclusion

As you’ve seen here, the cheerio library makes web scraping easy with its jQuery-esque syntax and blazing-fast operation. In this article, you learned how to do the following:

- Load and parse an HTML web page with cheerio
- Find elements with CSS selectors
- Extract data from elements
- Navigate the DOM
- Save scraped data into local file storage

You can find the complete code on [GitHub](https://github.com/heraldofsolace/cheerio-demo).

However, cheerio is just an HTML parser, so it can’t execute JavaScript code. That means you can’t use it for scraping dynamic web pages and single-page applications. To scrape those, you need to look beyond cheerio at complex tools like Selenium or Playwright. And that’s where Bright Data comes in. Bright Data’s vast web scraping solutions include a [Selenium Scraping Browser](/products/scraping-browser/selenium) and [Playwright Scraping Browser](/products/scraping-browser/playwright). To learn more about the products, you may visit our [Scraping Browser documentation](https://docs.brightdata.com/scraping-automation/scraping-browser/introduction).

[Scraping Browser free trial](#hs-signup)



Contact usStart free trial

No credit card required













Aniket Bhattacharyea









 [ View all articles ](https://brightdata.com/blog/authors/aniket-bhattacharyea)











 Table of Contents







Dedicated Scraper APIs &amp; No-Code Scrapers

Over 1000 scrapers for all popular domains. Simplify your web scraping.

[See pricing](/pricing/web-scraper "See pricing")

Just want data? Skip scraping.

Hundreds of ready-to-use datasets from all popular domains.

[See pricing](/pricing/datasets "See pricing")







 [ ](https://news.ycombinator.com/submitlink?t=Using+Cheerio+NPM+for+Web+Scraping&u=https://brightdata.com/blog/how-tos/cheerio-npm-web-scraping) [ ](https://www.linkedin.com/shareArticle?mini=true&title=Using+Cheerio+NPM+for+Web+Scraping&url=https://brightdata.com/blog/how-tos/cheerio-npm-web-scraping) [ ](http://www.reddit.com/submit?title=Using+Cheerio+NPM+for+Web+Scraping&url=https://brightdata.com/blog/how-tos/cheerio-npm-web-scraping)







##  You might also be interested in

 [ ](https://brightdata.com/blog/web-data/best-languages-web-scraping "The 5 Best Programming Languages for Web Scraping")

 [Web Data





Daniel Shashko

Web Data &amp; AI Expert





### The 5 Best Programming Languages for Web Scraping

Learn abou the 5 best web scraping languages: JavaScript, Python, Ruby, PHP, and C++.



 25-May-2023

 4 min read

 ](https://brightdata.com/blog/web-data/best-languages-web-scraping)

 [ ](https://brightdata.com/blog/how-tos/playwright-web-scraping "A Guide to Playwright Web Scraping in 2026")

 [How Tos





Antonello Zanini

Technical Writer





### A Guide to Playwright Web Scraping in 2026

Web scraping with Playwright: A step-by-step guide to extracting data using this powerful tool.



 19-May-2023

 17 min read

 ](https://brightdata.com/blog/how-tos/playwright-web-scraping)

 [ ](https://brightdata.com/blog/web-data/cheerio-vs-puppeteer "Cheerio vs. Puppeteer for Web Scraping")

 [Web Data





Gints Dreimanis





### Cheerio vs. Puppeteer for Web Scraping

A look at the differences between Puppeteer and Cheerio, by building a web scraper with both.



 09-Feb-2023

 8 min read

 ](https://brightdata.com/blog/web-data/cheerio-vs-puppeteer)
