Selecting Elements

Cheerio finds elements using CSS selectors, the same syntax you would use in a stylesheet or in document.querySelectorAll. This guide covers the selectors you’ll reach for most often, and where to look for the rest.

Start by loading a document. The load call returns the $ function, which is what you pass selectors to:

import * as cheerio from 'cheerio';

const $ = cheerio.load('<html>...</html>');

Tip

By convention, variables holding a Cheerio object are prefixed with $. It’s not required, but it makes code much easier to scan.

Basic selectors

SelectorMatches
$('p')All <p> elements.
$('.selected')All elements with the class selected.
$('#main')The element with the id main.
$('[data-selected=true]')All elements whose data-selected is true.
$('*')Every element in the document.

The examples on this page are live — edit them and press Run.

Example
const $ = cheerio.load(`
  <article id="post">
    <h1>Cheerio</h1>
    <p class="intro">Fast, flexible, and lean.</p>
    <p data-kind="note">Not a web browser.</p>
    <p>Hello from the last paragraph.</p>
  </article>
`);

console.log('By tag:', $('p').length);
console.log('By class:', $('.intro').text());
console.log('By id:', $('#post h1').text());
console.log('By attribute:', $('[data-kind=note]').text());

XML namespaces

Namespaced attributes can be selected, but the CSS specification requires the colon (:) to be escaped:

$('[xml\\:id="main"]');

Combining selectors

Write selectors next to each other to require that an element match all of them:

// <p> elements that also have the class `selected`
const $selected = $('p.selected');

Separate selectors with a comma to match any of them:

// All <h1> and <h2> elements
const $headings = $('h1, h2');

Selecting by relationship

Combinators describe where an element sits relative to another:

SelectorMatches
$('div p')<p> elements anywhere inside a <div>.
$('div > p')<p> elements that are direct children of a <div>.
$('h2 + p')The <p> immediately following an <h2>.
$('h2 ~ p')All <p> elements following an <h2> under the same parent.

Note the difference between the first two: div p reaches the <p> nested inside the <ul>, while div > p stops at the direct children.

Example
const $ = cheerio.load(`
  <div>
    <h2>Fruit</h2>
    <p>Apple</p>
    <p>Banana</p>
    <ul><li><p>Cherry</p></li></ul>
  </div>
`);

console.log('div p:', $('div p').length); // 3 — includes the nested one
console.log('div > p:', $('div > p').length); // 2 — direct children only
console.log('h2 + p:', $('h2 + p').text());
console.log('h2 ~ p:', $('h2 ~ p').length);

Beyond standard CSS

Cheerio’s selector engine, css-select, supports most standard pseudo-classes — see its README for the exact list — plus :contains(), which matches on text. On top of that, cheerio-select adds jQuery’s positional extensions — :first, :last, and :eq(n). These are not valid CSS and won’t work in a browser, but they’re handy when scraping.

Example
const $ = cheerio.load(`
  <ul>
    <li>Apple</li>
    <li>Banana</li>
    <li>Cherry</li>
  </ul>
`);

console.log(':contains:', $('li:contains("an")').text());
console.log(':first:', $('li:first').text());
console.log(':last:', $('li:last').text());
console.log(':eq(1):', $('li:eq(1)').text()); // zero-based

You can also define your own pseudo-classes — see Extending Cheerio.

Where to go next

Once you have a selection, use the traversal methods to move around it, or the manipulation methods to change it.

For more on selectors themselves, see MDN and jQuery’s guide to selecting elements.