In Cheerio, you can loop through elements with specific classes or IDs using several methods. The most common approach is the .each()
method, which allows you to iterate over a selection of elements and execute a function for each matched element.
Looping Through Elements with a Class
Use the class selector (.classname
) with the .each()
method to iterate through all elements with a specific class:
const cheerio = require('cheerio');
const html = `
<div class="product">Product 1</div>
<div class="product">Product 2</div>
<span class="product">Product 3</span>
`;
const $ = cheerio.load(html);
// Loop through all elements with class 'product'
$('.product').each((index, element) => {
const $element = $(element);
console.log(`Item ${index}: ${$element.text()}`);
});
// Output:
// Item 0: Product 1
// Item 1: Product 2
// Item 2: Product 3
Extracting Data from Class Elements
Here's a practical example of extracting structured data from elements with the same class:
const html = `
<div class="user-card">
<h3>John Doe</h3>
<p>john@example.com</p>
</div>
<div class="user-card">
<h3>Jane Smith</h3>
<p>jane@example.com</p>
</div>
`;
const $ = cheerio.load(html);
const users = [];
$('.user-card').each((index, element) => {
const $card = $(element);
users.push({
name: $card.find('h3').text(),
email: $card.find('p').text()
});
});
console.log(users);
// Output: [
// { name: 'John Doe', email: 'john@example.com' },
// { name: 'Jane Smith', email: 'jane@example.com' }
// ]
Looping Through Elements with an ID
While IDs should be unique per HTML document, you can still use .each()
for consistency or when dealing with malformed HTML:
const html = `<div id="main-content">Content here</div>`;
const $ = cheerio.load(html);
$('#main-content').each((index, element) => {
console.log($(element).text());
});
For unique IDs, direct access is more efficient:
const content = $('#main-content').text();
console.log(content);
Alternative Iteration Methods
Using .map()
for Data Transformation
Convert elements to an array of values:
const prices = $('.price').map((index, element) => {
return parseFloat($(element).text().replace('$', ''));
}).get(); // .get() converts Cheerio object to regular array
console.log(prices); // [19.99, 29.99, 15.50]
Using .filter()
for Conditional Selection
Filter elements before iteration:
// Only process elements with specific attributes
$('.product').filter((index, element) => {
return $(element).attr('data-available') === 'true';
}).each((index, element) => {
console.log(`Available: ${$(element).text()}`);
});
Complex Selectors
Combine selectors for more specific targeting:
// Multiple classes
$('.product.featured').each((index, element) => {
console.log('Featured product:', $(element).text());
});
// Class with attribute
$('.item[data-category="electronics"]').each((index, element) => {
console.log('Electronics item:', $(element).text());
});
// Nested elements
$('.container .item').each((index, element) => {
console.log('Container item:', $(element).text());
});
Error Handling and Best Practices
const $ = cheerio.load(html);
$('.product').each((index, element) => {
try {
const $element = $(element);
const title = $element.find('.title').text().trim();
const price = $element.find('.price').text().trim();
if (title && price) {
console.log(`${title}: ${price}`);
}
} catch (error) {
console.error(`Error processing element ${index}:`, error);
}
});
Key Points to Remember
- The
.each()
method callback receives(index, element)
parameters element
is a raw DOM element - wrap with$(element)
for Cheerio methods- Use
.get()
after.map()
to convert to a regular JavaScript array - Cheerio doesn't execute JavaScript - use Puppeteer for dynamic content
- Always validate extracted data before using it in your application