FAQ Cheerio
Quelle est la rapidité de Cheerio comparé aux autres bibliothèques d'analyse HTML ?
Cheerio est conçu pour la vitesse et l'efficacité. Il utilise un modèle DOM léger basé sur domhandler, qui est significativement plus rapide que les implémentations DOM complètes de navigateur comme JSDOM. Contrairement aux solutions basées sur navigateur, Cheerio supprime les incohérences DOM et la surcharge du navigateur, résultant en des opérations d'analyse et de manipulation ultra-rapides.
import * as cheerio from 'cheerio';
// Fast parsing - no browser overhead
const $ = cheerio.load('<div>Large HTML document...</div>');
// Efficient manipulation
$('div').addClass('processed').attr('data-timestamp', Date.now());
Pour les documents volumineux ou le traitement par lots, envisagez d'utiliser les API de streaming comme cheerio.stringStream() pour une utilisation optimale de la mémoire.
Quand devrais-je utiliser Cheerio au lieu du DOM navigateur ou JSDOM ?
Utilisez Cheerio pour l'analyse HTML côté serveur, le web scraping et la manipulation HTML statique. Il est idéal quand vous avez besoin de la syntaxe jQuery sans la surcharge du navigateur. Choisissez le DOM navigateur pour les interactions côté client, JSDOM pour la simulation complète du navigateur, ou Puppeteer pour le scraping de contenu dynamique.
// Perfect for server-side scraping
const $ = cheerio.load(htmlResponse);
const titles = $('h1, h2, h3').map((i, el) => $(el).text()).get();
// Great for email template processing
const emailHtml = cheerio.load(template);
emailHtml('.username').text(user.name);
emailHtml('.content').html(processedContent);
Comment gérer les différents analyseurs HTML dans Cheerio ?
Cheerio supporte à la fois htmlparser2 (rapide, tolérant) et parse5 (conforme aux standards). Le choix dépend de vos besoins : utilisez htmlparser2 pour la vitesse et la flexibilité avec le HTML malformé, ou parse5 pour une conformité stricte HTML5.
// Using htmlparser2 (default, faster)
const $ = cheerio.load(html, {
xml: false,
decodeEntities: true
});
// Using parse5 (more compliant)
const $strict = cheerio.load(html, {
_useHtmlParser2: false,
xml: false
});
// For XML documents
const $xml = cheerio.load(xmlString, {
xmlMode: true,
decodeEntities: true
});
Quelle est la différence entre .attr(), .prop() et .data() ?
.attr()gère les attributs HTML comme des chaînes de caractères.prop()gère les propriétés DOM avec coercition de type et valeurs calculées.data()gère les attributs de données HTML5 avec analyse JSON automatique
const $ = cheerio.load('<input type="checkbox" checked data-config=\'{"enabled": true}\'>');
// Attributes (string values)
$('input').attr('checked'); // 'checked'
$('input').attr('type'); // 'checkbox'
// Properties (computed/coerced values)
$('input').prop('checked'); // true (boolean)
$('input').prop('tagName'); // 'INPUT'
// Data attributes (with JSON parsing)
$('input').data('config'); // { enabled: true } (object)
Comment gérer correctement les types TypeScript avec Cheerio ?
Importez les types explicitement et utilisez les paramètres génériques pour une meilleure sécurité de type. La bibliothèque fournit un support TypeScript complet avec inférence de type appropriée.
import * as cheerio from 'cheerio';
import type { CheerioAPI, Cheerio, Element } from 'cheerio';
// Type the main API
const $: CheerioAPI = cheerio.load('<div>Content</div>');
// Type specific selections
const $elements: Cheerio<Element> = $('div');
// Use proper typing for element extraction
const elements: Element[] = $('div').get();
const firstElement: Element | undefined = $('div').get(0);
// Type function parameters correctly
$('div').each(function(this: Element, index: number) {
// 'this' is properly typed as Element
const $this = $(this);
});
Pourquoi est-ce que j'obtiens des erreurs "Cannot read property of undefined" ?
Cela arrive généralement quand les sélecteurs ne correspondent à aucun élément. Vérifiez toujours si les éléments existent avant de chaîner les méthodes ou d'accéder aux propriétés.
// ❌ Dangerous - may throw if no elements found
const title = $('.title').text().toUpperCase();
// ✅ Safe approach
const $title = $('.title');
const title = $title.length > 0 ? $title.text().toUpperCase() : '';
// ✅ Alternative with optional chaining
const title = $('.title').first().text() || '';
// ✅ Check before manipulating
if ($('.content').length > 0) {
$('.content').addClass('processed');
}
Comment gérer les documents HTML ou XML malformés ?
Cheerio est tolérant avec le HTML malformé lors de l'utilisation de htmlparser2. Pour une analyse stricte, utilisez l'analyseur parse5 ou activez le mode XML pour les documents XML bien formés.
// Forgiving HTML parsing (default)
const $ = cheerio.load('<div><p>Unclosed paragraph</div>');
// Strict XML parsing
const $xml = cheerio.load('<root><item/></root>', {
xmlMode: true,
withStartIndices: false,
withEndIndices: false
});
// Handle parsing errors gracefully
try {
const $ = cheerio.load(possiblyBadHTML);
return $('title').text();
} catch (error) {
console.error('HTML parsing failed:', error);
return '';
}
Comment traiter efficacement de gros documents HTML ?
Pour les documents volumineux, utilisez les API de streaming pour éviter de charger tout en mémoire d'un coup. C'est particulièrement important pour le web scraping ou le traitement de gros fichiers.
import * as cheerio from 'cheerio';
import { createReadStream } from 'fs';
// Stream processing for large files
const stream = cheerio.stringStream({}, (err, $) => {
if (err) throw err;
// Process the document
const data = $('h1, h2, h3').map((i, el) => $(el).text()).get();
console.log(data);
});
createReadStream('large-file.html', { encoding: 'utf8' }).pipe(stream);
// For URLs with automatic encoding detection
const $ = await cheerio.fromURL('https://example.com', {
encoding: { defaultEncoding: 'utf8' }
});
Quelles sont les implications mémoire de l'utilisation de Cheerio ?
Cheerio crée des représentations DOM légères qui utilisent moins de mémoire que les DOM complets de navigateur. Cependant, faites attention à garder des références vers de gros documents ou créer de nombreuses instances Cheerio simultanément.
// ✅ Good - reuse the same instance
const $ = cheerio.load(html);
const results = [];
$('article').each((i, article) => {
const $article = $(article);
results.push({
title: $article.find('h1').text(),
content: $article.find('.content').text()
});
});
// ❌ Avoid - creates many instances
const articles = $('article').map((i, article) => {
return cheerio.load(article); // Don't do this
}).get();
Comment cloner des éléments sans casser les références ?
Utilisez la méthode .clone() pour créer des copies profondes d'éléments. C'est essentiel quand vous devez réutiliser des éléments plusieurs fois ou éviter de modifier les éléments originaux.
const $ = cheerio.load('<div class="template">Template content</div>');
// Clone before modifying
const $template = $('.template');
const $copy1 = $template.clone().addClass('instance-1').text('Instance 1');
const $copy2 = $template.clone().addClass('instance-2').text('Instance 2');
// Original remains unchanged
console.log($template.text()); // 'Template content'
// Append clones to different parents
$('#container1').append($copy1);
$('#container2').append($copy2);
Comment extraire efficacement des données structurées depuis le HTML ?
Utilisez la méthode .extract() pour les modèles d'extraction de données complexes. Elle fournit une façon déclarative d'extraire plusieurs valeurs des documents avec un support TypeScript approprié.
const $ = cheerio.load(productPageHtml);
// Extract structured data with type safety
const productData = $.root().extract({
title: 'h1.product-title',
price: '.price .amount',
images: [{ selector: '.gallery img', value: 'src' }],
features: ['.features li'],
specifications: {
selector: '.specs',
value: {
weight: '.weight',
dimensions: '.dimensions',
model: { selector: '.model', value: 'data-model' }
}
}
});
// Result is properly typed
console.log(productData.title); // string | undefined
console.log(productData.images); // string[]
console.log(productData.specifications?.model); // string | undefined
Quelles sont les bonnes pratiques pour la performance des sélecteurs CSS ?
Utilisez des sélecteurs spécifiques et évitez les requêtes trop complexes. Les sélecteurs d'ID sont les plus rapides, suivis des sélecteurs de classe, puis des sélecteurs d'attributs. Évitez les sélecteurs descendants profonds quand c'est possible.
// ✅ Fast - specific selectors
const $navItems = $('#navigation .nav-item');
const $activeButton = $('.btn.active');
// ❌ Slower - overly complex selectors
const $badSelector = $('div > div > div span.small[data-type="special"]');
// ✅ Better - break down complex selections
const $container = $('.content-area');
const $items = $container.find('[data-type="special"]');
// ✅ Cache frequently used selections
const $document = $.root();
const $body = $document.find('body');
Comment gérer correctement les données de formulaire et la sérialisation ?
Utilisez .serializeArray() pour les données structurées et .serialize() pour les chaînes encodées URL. Ces méthodes gèrent automatiquement les règles de validation de formulaire et les types d'éléments.
const $ = cheerio.load(formHtml);
// Get structured form data
const formData = $('form').serializeArray();
// [{ name: 'email', value: 'user@example.com' }, ...]
// Get URL-encoded string
const queryString = $('form').serialize();
// 'email=user@example.com&name=John'
// Handle specific form elements
const selectedOptions = $('select[multiple]').val(); // string[]
const checkboxValue = $('input[type="checkbox"]:checked').val(); // string | undefined
// Set form values programmatically
$('input[name="email"]').val('new@example.com');
$('select').val(['option1', 'option2']); // for multiple select
Comment modifier en toute sécurité les attributs HTML pour prévenir les attaques XSS ?
Cheerio encode automatiquement les valeurs d'attributs pour prévenir les attaques XSS. Cependant, soyez prudent avec l'insertion de contenu HTML et validez toujours les entrées utilisateur.
const $ = cheerio.load('<div></div>');
// ✅ Safe - attributes are automatically encoded
const userInput = '<script>alert("XSS")</script>';
$('div').attr('title', userInput);
// Result: <div title="<script>alert("XSS")</script>"></div>
// ✅ Safe text insertion
$('div').text(userInput); // Automatically escaped
// ❌ Dangerous - raw HTML insertion
$('div').html(userInput); // Don't do this with user input
// ✅ Better - sanitize first or use text()
$('div').text(sanitizeInput(userInput));
Quelle est la bonne façon de gérer les opérations asynchrones avec Cheerio ?
Cheerio lui-même est synchrone, mais vous pouvez le combiner avec des opérations async pour des tâches comme récupérer des URL ou traiter plusieurs documents de manière concurrente.
// Load from URL (async)
const $ = await cheerio.fromURL('https://example.com');
const title = $('title').text();
// Process multiple URLs concurrently
const urls = ['https://site1.com', 'https://site2.com'];
const results = await Promise.all(
urls.map(async (url) => {
const $ = await cheerio.fromURL(url);
return {
url,
title: $('title').text(),
links: $('a[href]').map((i, el) => $(el).attr('href')).get()
};
})
);
// Combine with other async operations
async function processDocument(html: string) {
const $ = cheerio.load(html);
// Extract image URLs
const imageUrls = $('img[src]').map((i, el) => $(el).attr('src')).get();
// Process images asynchronously
const processedImages = await Promise.all(
imageUrls.map(url => processImage(url))
);
return { processedImages };
}