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
| Selector | Matches |
|---|---|
$('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.
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:
| Selector | Matches |
|---|---|
$('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.
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.
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-basedYou 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.