

در این راهنمای عملی یاد میگیرید چگونه با Cheerio در محیط Node.js صفحات HTML را بارگذاری، پرسوجو و دادهها را استخراج کنید؛ از نصب و خواندن فایلهای محلی یا درخواست HTTP گرفته تا نمونهی کامل یک اسکریپر که خروجی JSON تولید میکند. مخاطب فرضی این مقاله توسعهدهندهی پایتون/Node در سطح متوسط است که دنبال جزئیات پیادهسازی، مدیریت خطا و نکات عملی برای تولید اسکریپر پایدار است.
نکته: Cheerio جاوااسکریپتِ سمت کلاینت را اجرا نمیکند؛ برای صفحات داینامیک باید از راهکارهای جایگزین استفاده کنید.
مراحل پایهای برای شروع:
mkdir web-scraping
cd web-scraping
npm init -y
npm install cheerio axios
توضیح: با npm init -y یک package.json پایه ساخته میشود. اگر میخواهید از import/export استفاده کنید، مقدار "type":"module" را در فایل package.json قرار دهید.
دو منبع اصلی HTML عبارتند از درخواست HTTP و فایل محلی. در هر دو حالت خروجی یک رشته HTML است که به cheerio.load پاس میدهیم تا تابع انتخابگر $ را بدست آوریم.
مثال: گرفتن HTML از وب با axios (با مدیریت خطا و هدر)
import * as cheerio from 'cheerio'
import axios from 'axios'
async function fetchHtml(url) {
try {
const response = await axios.get(url, {
headers: { 'User-Agent': 'Mozilla/5.0 (compatible; MyScraper/1.0)'} ,
timeout: 10000
})
const html = response.data // خروجی: رشتهٔ HTML
return cheerio.load(html) // بازگشت: تابع انتخابگر $
} catch (err) {
console.error('fetchHtml error:', err.message)
throw err
}
}
توضیح خطبهخط: ورودی تابع fetchHtml یک url است؛ خروجی تابع یک تابع انتخابگر $ است که روی آن میتوان عملیات جستجو/تغییر انجام داد. ما هدر User-Agent و timeout تعیین کردیم تا رفتار قابلپیشبینیتری داشته باشیم.
خواندن از فایل محلی با fs/promises:
import * as cheerio from 'cheerio'
import fs from 'fs/promises'
async function loadFromFile(path) {
const html = await fs.readFile(path, 'utf8') // ورودی: مسیر فایل، خروجی: رشتهٔ HTML
return cheerio.load(html)
}
پس از بارگذاری HTML، از تابع $ مانند jQuery استفاده میکنیم. روشهای رایج: text(), attr(), each().
const $ = cheerio.load('Example ')
const title = $('title').text() // خروجی: متن داخل تگ title
// پیمایش لینکها
$('a').each((i, el) => {
const href = $(el).attr('href') // آدرس
const text = $(el).text() // متن لینک
console.log(i, text, href)
})
نکته: each آرگومانهای index و element را میگیرد؛ برای دسترسی دوباره به متدهای Cheerio باید عنصر را با $(element) بستهبندی کنید.
برای جابجایی در ساختار از متدهایی مثل find, children, parent, parents, next, prev استفاده کنید. این متدها ترکیبپذیرند و انعطاف بالایی در استخراج ساختار پیچیده میدهند.
// پیدا کردن همهٔ های داخل یک کانتِینر
const $container = $('.container')
const paragraphs = $container.find('p')
paragraphs.each((i, p) => console.log($(p).text()))
// گرفتن والد مستقیم
const parentClass = $('.some-child').parent().attr('class')
مثالهای بالا ورودی را میگیرند (انتخابگر یا عنصر) و خروجی معمولاً یک مجموعهٔ Cheerio است که میتوانید روی آن each اجرا کرده و دادهها را جمعآوری کنید.
برای استخراج الگوهای متنی مانند ایمیل یا شماره تلفن میتوانید از regex در ترکیب با text() یا html() استفاده کنید.
const emails = []
$('li').each((i, el) => {
const text = $(el).text()
const m = text.match(/\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b/)
if (m) emails.push(m[0])
})
برای فیلتر کردن مجموعهها از filter() و برای معکوس کردن شرطها از not() استفاده کنید.
Cheerio علاوه بر خواندن میتواند DOM را بهصورت برنامهای تغییر دهد: صفتها، کلاسها، متن یا ساختار HTML را ویرایش کنید.
const $ = cheerio.load('link')
const $a = $('a')
$a.attr('href', 'https://nodejs.org') // تغییر attribute
$a.prop('target', '_self') // تغییر property
$a.text('Node.js') // تغییر متن
خروجی این تغییرات را میتوانید با prop('outerHTML') یا html() مشاهده کنید.
مثال کامل که همهٔ مفاهیم بالا را جمع میکند: دریافت صفحه، انتخاب بلوکهای نقلقول، استخراج متن، نویسنده و تگها، و تولید آرایهٔ JSON.
import * as cheerio from 'cheerio'
import axios from 'axios'
async function scrapeQuotes(url) {
// ورودی: url (رشته)، خروجی: آرایهٔ اشیاء
const res = await axios.get(url, { timeout: 10000 })
const $ = cheerio.load(res.data)
const quotes = []
$('div.quote').each((i, block) => {
const quoteText = $(block).find('span.text').text().trim()
const author = $(block).find('small.author').text().trim()
const tags = []
$(block).find('a.tag').each((j, t) => tags.push($(t).text().trim()))
quotes.push({ No: i + 1, Quote: quoteText, Author: author, tags })
})
return quotes // خروجی: [{No, Quote, Author, tags}, ...]
}
// استفاده
scrapeQuotes('https://quotes.toscrape.com')
.then(data => console.log(JSON.stringify(data, null, 2)))
.catch(err => console.error('scrape error', err.message))
توضیح: تابع scrapeQuotes یک درخواست HTTP انجام میدهد، درخت DOM را با Cheerio میسازد و سپس بهصورت مرحلهای بلوکهای div.quote را پردازش میکند. خروجی مناسب برای ذخیره در فایل JSON یا تبدیل به CSV است.
محدودیت اصلی Cheerio این است که جاوااسکریپت اجرا نمیشود؛ اگر نیاز به رندر یا تعامل (کلیک، اسکرول) دارید از ابزارهای زیر استفاده کنید:
Cheerio ابزار قدرتمندی برای وب اسکریپینگ صفحات ایستا در Node.js است: سبک، سریع و با API آشنا. در عین حال باید محدودیتها (عدم اجرای JS، حافظه) را در طراحی اسکریپر در نظر بگیرید و بهترینروشها مانند مدیریت خطا، محدودسازی نرخ و رعایت اصول اخلاقی را اعمال کنید. با ترکیب Cheerio با ابزارهای شبکهای مانند axios و الگوهای مانند صفبندی و retry میتوانید اسکریپرهای قابلاعتماد و مقیاسپذیر بسازید.