

در وب اسکریپینگ، عملکرد یک اسپایدر امروز سالم بودنش را تضمین نمیکند؛ از فردا ممکن است تغییرات HTML، ضدباتها، افت پراکسی یا خطاهای سرور باعث خراب شدن اسکریپها شوند. در این مقاله میخواهیم چهار رویکرد عملی برای نظارت و حفظ سلامت اسپایدرهای Scrapy را بررسی کنیم، همراه با مثالهای پایتون، تنظیمات متداول، مزایا/معایب و توصیههای عملی برای استقرار در تولید.
Scrapy بهصورت پیشفرض یک لایهٔ قدرتمند لاگ و آمار (stats) دارد که در زمان اجرا متریکهای زیادی را ثبت میکند. این ابزار برای دیباگ محلی و توسعه عالی است، چون اطلاعاتی مثل تعداد درخواستها، وضعیت پاسخها، زمان اجرای کلی و تعداد آیتمهای استخراجشده را فراهم میکند.
نمونه خروجی لاگ/آمار (خروجی کنسول):
2021-12-17 17:02:25 [scrapy.statscollectors] INFO: Dumping Scrapy stats:
{'downloader/request_count': 5,
'downloader/response_status_count/200': 5,
'item_scraped_count': 50,
'elapsed_time_seconds': 2.600152,
'start_time': datetime.datetime(...)}
2021-12-17 17:02:25 [scrapy.core.engine] INFO: Spider closed (finished)
چطور آمار سفارشی اضافه کنیم؟ فرض کنید میخواهیم شمار صفحات خاص یا انواع خطا را افزایش دهیم؛ داخل اسپایدر یا middleware از crawler.stats استفاده میکنیم:
# مثال: my_spider.py (قسمتهایی مرتبط)
class MySpider(scrapy.Spider):
name = 'myspider'
def parse(self, response):
# افزایش آمار سفارشی
self.crawler.stats.inc_value('my_spider/special_pages')
# بقیه منطق پارس
...
ورودی: شیٔ response و crawler (از Scrapy). خروجی: افزایش یک متریک عددی که در فایل آمار/لاگ ظاهر میشود.
محدودیتها و نکات عملی:
مزایا:
معایب:
ابزارهای اختصاصی مانیتورینگ برای وب اسکریپینگ (مثل نمونههای تجاری/جامعهای) معمولاً با چند خط کدنویسی آمار را جمعآوری، داشبورد میسازند، چکهای سلامت خودکار اجرا میکنند و در صورت مشکل شما را اطلاعرسانی میکنند. مزیت بزرگ این رویکرد، کاهش زمان راهاندازی و داشتن قابلیتهایی که بهصورت اختصاصی برای وب اسکریپینگ مفیدند: دادهسنجی فیلدها، مقایسهٔ تاریخی، و هشدارهای هوشمند.
نمونه معمول نصب (خط فرمان):
pip install scrapeops-scrapy
نمونه تنظیمات سادهای که به settings.py اضافه میشود (ورودی: API key و نام پلاگین):
# settings.py
SCRAPEOPS_API_KEY = 'YOUR_API_KEY'
EXTENSIONS = {
'scrapeops_scrapy.extension.ScrapeOpsMonitor': 500,
}
DOWNLOADER_MIDDLEWARES = {
'scrapeops_scrapy.middleware.retry.RetryMiddleware': 550,
'scrapy.downloadermiddlewares.retry.RetryMiddleware': None,
}
ورودی: کلید API و فعالسازی extension. خروجی: ارسال خودکار آمار، داشبورد و تنظیمات هشداردهی.
نکات عملی:
مزایا:
معایب:
Spidermon یک افزونهٔ متنباز برای Scrapy است که اجازه میدهد تستها/مانیتورهای سفارشی روی آیتمها و شاخصهای اجرای job بنویسید. بر خلاف لاگ ساده، این ابزار اجازه میدهد قواعد اعتبارسنجی (مانند وجود فیلدهای ضروری، نوع داده صحیح یا حداقل تعداد آیتم) را بهصورت تست بنویسید و در ابتدای، میانه یا انتهای اجرا اجرا کنید.
نصب پایه:
pip install spidermon
فعالسازی در settings.py (ورودی: فعال/غیرفعال کردن):
# settings.py
SPIDERMON_ENABLED = True
EXTENSIONS = {
'spidermon.contrib.scrapy.extensions.Spidermon': 500,
}
نمونهٔ یک مانیتور ساده که تعداد آیتمها را بررسی میکند (ورودی: آمار Scrapy، خروجی: PASS/FAIL و گزارش در لاگ):
# my_project/monitors.py
from spidermon import Monitor, MonitorSuite, monitors
@monitors.name('Item count')
class ItemCountMonitor(Monitor):
@monitors.name('Minimum number of items')
def test_minimum_number_of_items(self):
item_extracted = getattr(self.data.stats, 'item_scraped_count', 0)
minimum_threshold = 10
msg = 'Extracted less than {} items'.format(minimum_threshold)
self.assertTrue(item_extracted >= minimum_threshold, msg=msg)
class SpiderCloseMonitorSuite(MonitorSuite):
monitors = [
ItemCountMonitor,
]
این مانیتور در پایان اجرا مقدار item_scraped_count را میخواند و در صورت کمتر بودن از آستانه شکست را لاگ میکند؛ سپس میتوانید با log parsing یا ارسال ایمیل/Slack اقدامات لازم را انجام دهید.
محدودیتها:
مزایا:
معایب:
راه دیگر این است که لاگها و متریکهای Scrapy را به ابزارهای مانیتورینگ عمومی مثل پلتفرمهای لاگ/متریک و APM بفرستید. این ابزارها قابلیتهای مانیتورینگ، هشداردهی و تحلیل پیشرفتهای دارند، اما برای وب اسکریپینگ باید سفارشیسازی زیادی انجام دهید.
نکات عملی:
نمونهٔ یک اسپایدر ساده که خطاها را لاگ و متریک میفرستد:
import scrapy
class ExampleSpider(scrapy.Spider):
name = 'example'
def start_requests(self):
urls = ['https://example.com']
for u in urls:
yield scrapy.Request(u, callback=self.parse, errback=self.errback)
def parse(self, response):
# افزایش یک متریک دلخواه
self.crawler.stats.inc_value('example/pages_scraped')
# پردازش و استخراج آیتم
item = {'title': response.css('title::text').get()}
yield item
def errback(self, failure):
# لاگ و افزایش شمارش خطا
self.logger.error('Request failed: %s', failure.value)
self.crawler.stats.inc_value('example/request_errors')
ورودی: URLها و پاسخها، خروجی: آیتمها و متریکهایی که برای مانیتورینگ استفاده میشوند.
برای یک سیستم مانیتورینگ اثربخش در وب اسکریپینگ: در توسعه روی لاگها و آمار داخلی Scrapy سرمایهگذاری کنید، برای اعتبارسنجی دادهها از Spidermon استفاده کنید و برای محیط تولید از یک راهکار متمرکز (یا سرویس اختصاصی) برای داشبورد، health checks و alerting بهره ببرید. ترکیب این ابزارها به شما کمک میکند تا تغییرات سایتها، افت کیفیت داده یا مشکلات زیرساخت را سریعتر شناسایی و رفع کنید.


