К основному содержанию
правило

cheerio — правило для Cursor: парсинг HTML и установка

Правило задаёт практики для cheerio в Node.js: структура скрейперов, выбор селекторов, очистка данных и тесты.

Установить в Cursor · Вручную: положить файлы Все способы и платформы ↓
.cursor/rules/cheerio.mdc
Открыть на GitHub

Что делает cheerio

Правило применяется к файлам **/*.{js,jsx} и задаёт структуру для скрейперов на Node.js. Оно разделяет HTTP-запросы, разбор HTML и сохранение данных, советует использовать async/await, точные селекторы и проверку существования элементов перед извлечением. Для текста нужен .text().trim(), для атрибутов — .attr().

Для больших документов правило учитывает память cheerio.load(), а для очередей, повторных запросов и ограничения частоты предлагает Crawlee с CheerioCrawler. Логику разбора следует проверять на моковом HTML через Jest. cheerio не выполняет JavaScript и не рендерит CSS, поэтому динамический контент потребует Puppeteer или Playwright. Для скрейпинга также нужно соблюдать robots.txt.

Какие задачи решает

  • разделить запросы, разбор HTML и сохранение данных
  • выбрать узкие селекторы для нужного блока страницы
  • очистить извлечённый текст от пробелов
  • обработать отсутствующие элементы и атрибуты
  • протестировать парсер на моковом HTML

Примеры запросов агенту

  • Настрой разбор товаров через cheerio: используй scoped-селекторы, .text().trim() и сохрани результат в products.json.
  • Раздели скрейпер на получение HTML, парсинг и запись данных, используя async/await и обработку ошибок.
  • Напиши Jest-тест для parser.test.js, который проверяет найденные и отсутствующие элементы в HTML.

Как установить cheerio

Вручную: положить файлы

.cursor/rules/cheerio.mdc

Во frontmatter: description, globs, alwaysApply

По шагам, с командами для каждой платформы: Cursor rules: файлы .mdc, четыре режима и замена .cursorrules

Вопросы о cheerio

Как установить cheerio в Cursor?

Скопируйте файл правила в .cursor/rules/cheerio.mdc. Cursor применит его к файлам **/*.{js,jsx}.

Что делает правило cheerio?

Оно задаёт практики для HTML-парсинга в Node.js: модульную структуру скрейпера, точные селекторы, очистку текста, проверки отсутствующих элементов и тестирование.

Что делать с динамическим HTML, который появляется через JavaScript?

cheerio работает с исходной HTML-строкой и не выполняет JavaScript. Для такого контента правило советует использовать Puppeteer или Playwright.

Исходный текст

cheerio.mdc · CC0-1.0
---
description: Definitive guidelines for using cheerio effectively in Node.js projects, focusing on robust web scraping, performance, and maintainable code.
globs: **/*.{js,jsx}
---
# cheerio Best Practices

`cheerio` is your lightweight, server-side jQuery for Node.js, ideal for fast HTML parsing and manipulation. Follow these rules to build efficient, maintainable, and robust scraping solutions.

## 1. Code Organization & Structure

**Always modularize your scraping logic.** Separate HTTP requests, HTML parsing, and data persistence. Use `async/await` for all asynchronous operations.

### ✅ GOOD: Modular & Asynchronous Structure

```javascript
// index.js
import * as cheerio from 'cheerio';
import axios from 'axios';
import { writeFile } from 'fs/promises';

async function fetchAndParse(url) {
  try {
    const { data: html } = await axios.get(url, {
      headers: { 'User-Agent': 'YourScraper/1.0' }
    });
    const $ = cheerio.load(html);

    const products = [];
    $('.product-item').each((i, el) => {
      const $el = $(el);
      const name = $el.find('.product-name').text().trim();
      const price = $el.find('.product-price').text().trim();
      const imageUrl = $el.find('img').attr('src');
      
      // Always check for existence before pushing
      if (name) { 
        products.push({ name, price, imageUrl });
      }
    });
    return products;
  } catch (error) {
    console.error(`Error scraping ${url}:`, error.message);
    throw error;
  }
}

async function main() {
  const targetUrl = 'https://www.example.com/products';
  const scrapedData = await fetchAndParse(targetUrl);
  await writeFile('products.json', JSON.stringify(scrapedData, null, 2), 'utf8');
  console.log('Scraping complete. Data saved to products.json');
}

main();
```

## 2. Common Patterns & Anti-patterns

### 2.1. Selector Efficiency

**Keep selectors specific and scoped.** Avoid broad selectors that force `cheerio` to traverse large portions of the DOM. Chain `.find()` for nested elements.

```javascript
// ❌ BAD: Overly broad, inefficient
const allLinks = $('a').map((i, el) => $(el).attr('href')).get();

// ✅ GOOD: Scoped to relevant section
const productLinks = $('#product-grid a.product-link').map((i, el) => $(el).attr('href')).get();

// ✅ GOOD: Chain .find() for precision
const productName = $('.product-card').first().find('h2.title').text().trim();
```

### 2.2. Data Extraction & Cleaning

**Use `.text()` for visible text, `.attr()` for attributes, `.html()` for inner HTML.** Always `.trim()` extracted text to remove whitespace.

```javascript
// ❌ BAD: Untrimmed text, can contain leading/trailing whitespace or newlines
const title = $('h1').text(); // "  My Product Title  \n"

// ✅ GOOD: Clean text extraction
const title = $('h1').text().trim(); // "My Product Title"

// ❌ BAD: Assuming element exists, `undefined.text()` will crash
const price = $('.product-price').text().trim(); 

// ✅ GOOD: Check element existence before extracting
const $priceEl = $('.product-price');
const price = $priceEl.length ? $priceEl.text().trim() : 'N/A';
```

## 3. Performance Considerations

### 3.1. Large HTML Documents (>10MB)

`cheerio.load()` creates an in-memory DOM. For very large documents, this can consume significant memory.

**Strategies for large documents:**
1.  **Selective Loading:** If possible, extract and parse only relevant HTML snippets.
2.  **Clear References:** Set `$` to `null` after processing to aid garbage collection.

```javascript
// ✅ GOOD: Aid garbage collection
let $ = cheerio.load(htmlContent);
// ... perform operations ...
$ = null; // Clear reference
if (global.gc) global.gc(); // Force GC (requires --expose-gc)
```

### 3.2. Concurrency & Rate Limiting

For scalable, production scraping, **use `Crawlee`'s `CheerioCrawler`**. It handles request queuing, concurrency, retries, and rate limiting automatically.

```javascript
// ✅ GOOD: Scalable scraping with Crawlee
import { CheerioCrawler, Dataset } from 'crawlee';

const crawler = new CheerioCrawler({
    maxRequestsPerMinute: 60, // Respect rate limits
    async requestHandler({ request, $, log }) {
        log.info(`Processing ${request.url}`);
        const title = $('h1').text().trim();
        await Dataset.pushData({ url: request.url, title });
    },
});

await crawler.run(['https://crawlee.dev']);
```

## 4. Common Pitfalls & Gotchas

### 4.1. Cheerio is NOT a Browser

**`cheerio` does not execute JavaScript, render CSS, or load external resources.** It only parses the raw HTML string.
**Solution:** For dynamic content rendered by client-side JavaScript, use browser automation tools like `Puppeteer` or `Playwright`.

### 4.2. Respect `robots.txt`

**Always check and respect a website's `robots.txt` file.** Ethical scraping is non-negotiable.

## 5. Testing Approaches

**Unit test your parsing logic with mocked HTML.** This ensures your selectors and extraction methods are robust and resilient to minor HTML changes.

```javascript
// parser.test.js (using Jest)
import * as cheerio from 'cheerio';

describe('Product Parser', () => {
  const mockHtml = `
    <div class="product-item">
      <img src="/img/prod1.jpg">
      <h2 class="product-name">Product A</h2>
      <span class="product-price">$19.99</span>
    </div>`;

  it('should extract product details correctly', () => {
    const $ = cheerio.load(mockHtml);
    const $product = $('.product-item');
    expect($product.find('.product-name').text().trim()).toBe('Product A');
    expect($product.find('.product-price').text().trim()).toBe('$19.99');
    expect($product.find('img').attr('src')).toBe('/img/prod1.jpg');
  });

  it('should handle missing elements gracefully', () => {
    const $ = cheerio.load('<div class="product-item"></div>');
    const $product = $('.product-item');
    expect($product.find('.non-existent').text().trim()).toBe(''); // Cheerio returns empty string
    expect($product.find('img').attr('src')).toBeUndefined(); // Cheerio returns undefined for missing attr
  });
});
```

© sanjeed5 · CC0-1.0 · sanjeed5/awesome-cursor-rules-mdc

Похожие правила IDE

Все правила IDE по теме «Бэкенд и API» →
beautifulsoup-parsing Mindrally Учит агента разбирать HTML и XML на Python с помощью BeautifulSoup. Пригодится для веб-скрейпинга, выгрузки таблиц и обработки битой разметки. CX Codex +1 877установок chrome-devtools mrgoonie Скилл запускает Puppeteer-скрипты из командной строки: скриншоты, клики, заполнение форм, замер Core Web Vitals и разбор сетевых запросов. CX Codex +1 737установок wechat-article-extractor freestylefly Вытаскивает заголовок, автора, время публикации и HTML-текст из ссылок на статьи WeChat Official Account. Пригодится, если нужно собрать их в структурированные данные. CX Codex +1 3 900установок web-access-claude-skill reason-machines Даёт агенту выбор между поиском, загрузкой страниц и управлением настоящим Chrome. Пригодится, когда сайт закрыт логином или рисуется на JS. CX Codex +1 965установок firecrawl-build-scrape firecrawl Скилл помогает встроить вызов Firecrawl /scrape в код продукта для извлечения данных со страницы. Он пригодится, когда URL уже известен и нужен чистый markdown или метаданные. CX Codex +1 61 700установок browsing-with-playwright bilalmk Скилл управляет браузером через Playwright MCP: открывает страницы, заполняет формы, кликает по элементам и извлекает данные. Нужен для веб-задач. CX Codex +1 1 700установок

Из того же набора240

Весь набор →
cloudflare Задаёт стандарты разработки под Cloudflare Workers и Pages в Cursor. Помогает писать stateless-код для edge-рантайма, подключать базы данных и следить за размером бандла. ★ 3 580звёзд репо click Правило задаёт рекомендации по созданию CLI на Python с библиотекой click. Помогает организовать команды, параметры, вывод и подсказки. ★ 3 580звёзд репо clerk Правило для Cursor задаёт жёсткие требования к аутентификации Clerk: PKCE, серверные проверки, короткие токены. Пригодится, когда в проекте уже есть Clerk и нужен порядок в безопасности. ★ 3 580звёзд репо circleci Задаёт стандарты оформления пайплайнов CircleCI в проекте. Помогает генерировать надёжные конфигурации с кэшированием, reusable-командами и параллельными тестами. ★ 3 580звёзд репо chakra-ui Правило для Cursor задаёт, как писать интерфейсы на Chakra UI v2: тема через токены, варианты компонентов через рецепты, стилевые пропсы вместо CSS. ★ 3 580звёзд репо c-sharp Задаёт правила оформления кода на C# для Cursor: от стиля Allman и именования сущностей до внедрения зависимостей и запрета блокирующих асинхронных вызовов. ★ 3 580звёзд репо bun Правило задаёт стиль JavaScript-кода в файлах .js и .jsx: предлагает использовать инструменты Bun, современные конструкции языка и понятную структуру проекта. ★ 3 580звёзд репо bottle Правило для Cursor задаёт структуру Bottle-проекта: модули вместо одного app.py, конфиг через app.config, валидация Pydantic. Пригодится, если пишете бэкенд на Bottle. ★ 3 580звёзд репо

Спонсоры проекта

Компании, которые помогают держать аналитику открытой