مقدمه
در وب اسکریپینگ، هدف شما استخراج داده از صفحاتِ متحرکِ وب است؛ ساختار HTML تغییر میکند، دفاعهای ضد بات ارتقا مییابد و ممکن است IPها بلوک شوند. از همین رو راهاندازی یک سیستم مانیتورینگ قوی برای اسکریپها ضروری است تا به محض بروز خطا یا افت کیفیت داده بتوانید سریعاً واکنش نشان دهید. در این مقاله به Spidermon میپردازیم: افزونهای برای Scrapy که مانیتورینگ، اعتبارسنجی آیتمها و ارسال نوتیفیکیشن را ساده میکند. پس از خواندن این راهنما شما خواهید توانست Spidermon را نصب کنید، مانیتور و MonitorSuite بسازید، اعتبارسنجی آیتمها را فعال کنید و در نهایت یک نمونهٔ انتها-به-انتها راهاندازی کنید.
Spidermon چیست و چه زمانی مفید است
Spidermon یک چارچوب مانیتورینگ برای Scrapy است که بر مبنای unittest ساخته شده و اجازه میدهد «تستهای واحد»(monitors) برای وضعیت اجرای اسپایدرها بنویسید. کاربردهای عملی:
- چک کردن تعداد آیتمهای استخراجشده نسبت به آستانهٔ مورد انتظار.
- اطمینان از عدم وجود خطاهای دانلود یا افزایش غیرعادی Retries.
- اعتبارسنجی فیلدهای آیتمها و آگاهسازی در صورت شکست قوانین داده.
Spidermon ساختار قابل توسعهای دارد: Monitors (تستها)، MonitorSuites (گروهبندی و زمانبندی)، Validators (اعتبارسنجی آیتم) و Actions (نوتیفیکیشنها و گزارشها).
نصب و ادغام Spidermon با پروژهٔ Scrapy
ابتدا بستهٔ پایتون را نصب کنید و سپس دو تغییر ساده در settings.py اعمال کنید.
pip install spidermonدر settings.py، Spidermon را فعال و افزونه را اضافه کنید. ورودیها: فایل تنظیمات پروژه؛ خروجی: Spidermon فعال در چرخهٔ اجرایی Scrapy.
# settings.py
SPIDERMON_ENABLED = True
EXTENSIONS = {
'spidermon.contrib.scrapy.extensions.Spidermon': 500,
}
توضیح خطبهخط:
- خط اول مقدار بولی برای فعالسازی Spidermon در زمان اجرا است.
- در EXTENSIONS افزونهٔ Spidermon با اولویت 500 اضافه میشود تا در زمان مناسب اجرا شود.
نکته: بعد از نصب باید خودتان مانیتورها، Validatorها و Actions را تعریف و در settings ثبت کنید.
Monitors — تستهای واحد برای وضعیت اجرای اسکریپر
یک Monitor در واقع کلاسهایی است که از unittest مشتق شدهاند و شرایط سلامت (مثل تعداد آیتم، تعداد ارور یا تایماوتها) را تست میکنند. Spidermon چند Monitor آماده دارد که میتوانید آستانهها را در تنظیمات قرار دهید و از آنها استفاده کنید.
مثلاً لیستی از Monitorهای آماده:
- ItemCountMonitor: مطمئن میشود حداقل تعداد آیتم استخراج شده است.
- ErrorCountMonitor: تعداد ارورها را با آستانه مقایسه میکند.
- RetryCountMonitor: بررسی میکند آیا درخواستها به حداکثر تلاش رسیدهاند یا خیر.
برای استفاده از Monitorهای آماده کافی است آستانهها را در تنظیمات قرار دهید یا Monitorهای سفارشی بسازید.
نمونهٔ یک Monitor سفارشی که تعداد آیتم را بررسی میکند:
# my_project/monitors.py
from spidermon import Monitor, monitors
@monitors.name('Item count')
class CustomItemCountMonitor(Monitor):
@monitors.name('Minimum number of items')
def test_minimum_number_of_items(self):
# ورودی: self.data.stats -> شامل آمار Scrapy
item_extracted = getattr(self.data.stats, 'item_scraped_count', 0)
minimum_threshold = 10
msg = 'Extracted less than {} items'.format(minimum_threshold)
# خروجی: AssertTrue باعث ثبت نتیجهٔ تست در گزارش میشود
self.assertTrue(item_extracted >= minimum_threshold, msg=msg)
توضیح:
- getattr(self.data.stats, 'item_scraped_count', 0) آمار آیتمهای استخراجشده را میخواند؛ اگر وجود نداشته باشد صفر بازمیگردد.
- آستانهٔ مورد نظر را در یک متغیر تعریف میکنیم تا قابل تنظیم باشد.
- در نهایت با self.assertTrue شرط را بررسی و در صورت شکست، پیغام مشخصی ثبت میشود.
MonitorSuites — زمانبندی و گروهبندی مانیتورها
MonitorSuite مشخص میکند که چه مانیتورهایی چه زمانی اجرا شوند و در صورت موفق یا شکست چه Actionsای اجرا گردد. سه نوع رایج:
- SPIDERMON_SPIDER_OPEN_MONITORS — اجرا زمان شروع اسپایدر.
- SPIDERMON_SPIDER_CLOSE_MONITORS — اجرا هنگام بسته شدن/پایان اسپایدر.
- SPIDERMON_PERIODIC_MONITORS — اجرا در فواصل زمانی تعریفشده.
نمونهٔ سادهٔ MonitorSuite که دو مانیتور را اجرا میکند:
# tutorial/monitors.py
from spidermon.core.suites import MonitorSuite
class SpiderCloseMonitorSuite(MonitorSuite):
monitors = [
CustomItemCountMonitor, # همان Monitor تعریفشده قبلی
]
monitors_finished_actions = [
# Actionهایی که بعد از اتمام (بدون خطا) اجرا میشوند
]
monitors_failed_actions = [
# Actionهایی که در صورت شکست اجرا میشوند
]
برای فعالسازی، آدرس کلاس MonitorSuite را در settings بنویسید:
# settings.py
SPIDERMON_SPIDER_CLOSE_MONITORS = (
'tutorial.monitors.SpiderCloseMonitorSuite',
)
Actions — واکنش بعد از اجرای مانیتورها
Actions تعیین میکنند وقتی مجموعهای از مانیتورها اجرا شد چه اتفاقی بیفتد: ارسال ایمیل، نوتیفیکیشن در اسلک/تلگرام، تولید گزارش فایل HTML و غیره. Spidermon چند Action آماده دارد اما میتوانید Action سفارشی هم بنویسید.
برای مثال ارسال پیام اسلک در صورت شکست MonitorSuite:
# settings.py
SPIDERMON_SLACK_SENDER_TOKEN = ''
SPIDERMON_SLACK_SENDER_NAME = ''
SPIDERMON_SLACK_RECIPIENTS = ['@yourself', '#yourprojectchannel']
و سپس افزودن Action به MonitorSuite:
from spidermon.contrib.actions.slack.notifiers import SendSlackMessageSpiderFinished
class SpiderCloseMonitorSuite(MonitorSuite):
monitors = [
ItemCountMonitor,
ItemValidationMonitor,
]
monitors_failed_actions = [
SendSlackMessageSpiderFinished,
]
نکات امنیتی و عملی:
- توکنها و اطلاعات حساس را در متغیرهای محیطی ذخیره کنید و در settings از خواندن محیط استفاده کنید، نه ذخیرهٔ مستقیم در کد.
- در پروژههای تیمی دسترسی به کانالها و توکنها را محدود کنید و لاگ حساس را ذخیره نکنید.
اعتبارسنجی آیتمها (Item Validation)
یکی از مزایای Spidermon پشتیبانی از اعتبارسنجی آیتمها با schematics یا JSON Schema است. این قابلیت به شما امکان میدهد قوانین دقیق دادهای برای فیلدها تعریف کنید و خطاهای قالب/نوع داده را شناسایی کنید.
نمونهٔ یک validator با schematics:
# validators.py
from schematics.models import Model
from schematics.types import URLType, StringType, ListType, DecimalType
class ProductItem(Model):
url = URLType(required=True)
name = StringType(required=True)
price = DecimalType(required=True)
features = ListType(StringType)
image_url = URLType()
چگونه فعال شود:
# settings.py
ITEM_PIPELINES = {
'spidermon.contrib.scrapy.pipelines.ItemValidationPipeline': 800,
}
SPIDERMON_VALIDATION_MODELS = (
'tutorial.validators.ProductItem',
)
توضیح: پس از فعالسازی، Spidermon آمار اعتبارسنجی را به Scrapy stats اضافه میکند (مثلاً تعداد فیلدهای ناموفق، تعداد آیتمهای ناموفق) که قابل استفاده در Monitorهاست.
نکتهٔ عملی: یک خطای رایج هنگام اسکریپ کردن—آدرسها ممکن است نسبی باشند. Validator URLType احتمالاً آنها را نامعتبر تشخیص میدهد؛ در این حالت یا باید قبل از اعتبارسنجی URLها را به مطلق تبدیل کنید یا validator را تطبیق دهید.
نمونهٔ انتها-به-انتها: پروژهٔ کوچک کتاب
در این مثال یک پروژهٔ Scrapy داریم که از سایت نمونه کتابها اسکریپ میکند، سپس Spidermon را یکپارچه میکنیم تا آیتمها را اعتبارسنجی و اجرای اسپایدر را مانیتور کند.
گامها بهطور خلاصه:
- ایجاد پروژه و اسپایدر
- تعریف آیتم
- نوشتن اسپایدر
- تعریف Validator
- ساختن Monitorها و MonitorSuiteها
- افزودن Actions (مثلاً اسلک)
نمونهٔ آیتم (items.py):
# items.py
import scrapy
class BookItem(scrapy.Item):
url = scrapy.Field()
title = scrapy.Field()
price = scrapy.Field()
نمونهٔ اسپایدر ساده (spiders/bookspider.py):
# spiders/bookspider.py
import scrapy
from spidermon_demo.items import BookItem
class BookSpider(scrapy.Spider):
name = 'bookspider'
start_urls = ['http://books.toscrape.com']
def parse(self, response):
# ورودی: response -> صفحهٔ HTML
for article in response.css('article.product_pod'):
book_item = BookItem(
url = article.css('h3 > a::attr(href)').get(),
title = article.css('h3 > a::attr(title)').get(),
price = article.css('.price_color::text').get(),
)
# خروجی: تولید یک آیتم برای Pipelineها
yield book_item
next_page_url = response.css('li.next > a::attr(href)').get()
if next_page_url:
yield response.follow(url=next_page_url, callback=self.parse)
توضیحات خطبهخط مهم:
- یک حلقه روی کارتهای محصول با CSS selector اجرا میشود.
- برای هر کارت یک BookItem ساخته میشود و فیلدها پر میشود.
- آدرس صفحهٔ بعدی گرفته و با response.follow دنبال میشود تا کراول صفحات پیوسته انجام شود.
نمونهٔ Monitorها که در بالا توضیح داده شد را میتوان برای این پروژه تعریف و سپس MonitorSuite برای اجرا در پایان کار یا بصورت دورهای تنظیم کرد. برای نمونه، یک MonitorSuite دورهای با فاصلهٔ 5 ثانیه (فقط برای دمو) به صورت زیر در settings تعریف میشود:
SPIDERMON_PERIODIC_MONITORS = {
'spidermon_demo.monitors.PeriodicMonitorSuite': 5, # seconds
}
و در MonitorSuite مشخص کنید که در صورت شکست Action ارسال شود (مثلاً اسلک).
بهترین روشها، محدودیتها و نکات عملی
- بهترین روش: آستانهها (thresholds) را واقعی و ملموس تعیین کنید؛ مقدار خیلی سخت باعث هشدارهای کاذب میشود و مقدار خیلی آسان باعث از دست رفتن مشکلات میشود.
- پایداری: برای سرویسهای دورهای از retry و backoff استفاده کنید و مانیتورها را طوری تنظیم کنید که هنگام قطعهای کوتاهمدت شبکه هشدار ندهند.
- امنیت: توکنها را در متغیر محیطی نگه دارید و لاگهای حساس را از گزارشها حذف کنید.
- performance: مانیتورهای پیچیده که زمانبر هستند را به صورت دورهای اجرا کنید و نه در هر رویداد؛ همچنین تولید گزارشهای بزرگ را به فایل یا S3 منتقل کنید تا بار روی پردازش اصلی کم شود.
- خطایابی: هنگام بروز خطا، ابتدا آمار Scrapy (Scrapy stats) را بررسی کنید؛ Spidermon آمار اعتبارسنجی و اجرای مانیتورها را به این آمار اضافه میکند.
جمعبندی
Spidermon یک ابزار کاربردی و منعطف برای مانیتورینگ پروژههای وب اسکریپینگ با Scrapy است. با تعریف Monitorها میتوانید شاخصهای سلامتِ اجرا را تست کنید، با Validatorها کیفیت دادهٔ خروجی را تضمین کنید و با Actions مانند اسلک یا گزارش فایل، تیم خود را از مشکلات آگاه سازید. ترکیب مانیتورهای دورهای و مانیتورهای انتهای-اسپایدر به شما امکان میدهد هم در زمان اجرا و هم پس از پایان کار کیفیت و پایداری اسکریپرها را مدیریت کنید.
پیشنهاد عملی: مراحل را به ترتیب پیادهسازی کنید — نصب Spidermon، تعریف Validator و pipeline، نوشتن چند Monitor ساده، ایجاد MonitorSuite و در نهایت وصل کردن یک Action برای نوتیفیکیشن. سپس آستانهها را بر اساس نتایج واقعی تنظیم کنید تا سیستم هشدار شما مفید و قابل اعتماد باشد.





