مقدمه
در این مقاله میخواهیم به صورت عملی یاد بگیریم چگونه پروژههای Scrapy را با Scrapyd در سرور مستقر کنیم، آنها را اجرا و کنترل کنیم و در نهایت با ابزارهای مدیریتی مثل ScrapeOps یک جریان تولیدی پایدار بسازیم. پس از خواندن این مطلب شما قادر خواهید بود Scrapyd را نصب کنید، پروژهها را deploy کنید، با API آن کار کنید، از wrapper پایتون استفاده کنید و نکات امنیتی و بهترین شیوهها را در محیط تولید پیادهسازی نمایید.
Scrapyd چیست و چرا استفاده میکنیم
Scrapyd یک سرویس ساده است که به شما اجازه میدهد پروژههای Scrapy را به صورت بسته (egg/zip) به سرور بفرستید و آنها را از راه دور اجرا/لغو/مدیریت کنید. ویژگیهای کلیدی:
- اجرای jobs (اجرای اسپایدرها) از راه دور.
- لغو یا توقف jobها.
- مدیریت نسخههای پروژه و مشاهده لاگها از راه دور.
- ارائه یک API JSON سبک برای کنترل برنامهریزی و وضعیت jobs.
مزیت اصلی این است که دیگر نیازی به اجرای اسپایدرها روی لپتاپ خود ندارید و میتوانید مدیریت متمرکز و خودکار روی چند سرور داشته باشید.
راهاندازی سریع Scrapyd
راهاندازی ساده است و برای تست میتوانید روی ماشین محلی اجرا کنید:
pip install scrapydو سپس:
scrapydبه صورت پیشفرض Scrapyd روی http://localhost:6800/ اجرا میشود. این آدرس یک رابط ساده و چند endpoint JSON دارد که برای استقرار و کنترل jobها استفاده میشود.
تبدیل و استقرار (eggify & deploy) پروژههای Scrapy
برای فرستادن پروژه به Scrapyd معمولاً از scrapyd-client استفاده میکنیم که فرایند "eggify" و آپلود را اتوماتیک میکند.
pip install git+https://github.com/scrapy/scrapyd-client.gitدر روت پروژه Scrapy یک فایل scrapyd.cfg دارید که باید endpoint استقرار را مشخص کند. یک نمونه ساده:
[settings]
default = demo.settings
[deploy]
#url = http://localhost:6800/
project = demoبرای استقرار محلی کافی است خط url را uncomment کنید:
[deploy]
url = http://localhost:6800/
project = demoو سپس دستور زیر را اجرا کنید:
scrapyd-deploy defaultنمونه خروجی موفقیتآمیز در ترمینال (خلاصه):
$ scrapyd-deploy default
Packing version 1640086638
Deploying to project "demo" in http://localhost:6800/addversion.json
Server response (200): {"node_name": "MY_SERVER", "status": "ok", "project": "demo", "version": "1640086638", "spiders": 1}توضیح خطوط خروجی:
- "Packing version ..." → یک نسخهی یکتای بستهی پروژه ساخته شده (timestamp یا id ورژن).
- URL نشان میدهد که به endpoint addversion.json ارسال شده است.
- در پاسخ سرور اطلاعات پروژه، ورژن و تعداد اسپایدرها مشاهده میشود.
چند مقصد استقرار (deploy targets)
میتوانید چندین مقصد در scrapyd.cfg تعریف کنید تا بین local و production جابهجا شوید:
[settings]
default = demo.settings
[deploy:local]
url = http://localhost:6800/
project = demo
[deploy:production]
url = http://MY_IP_ADDRESS:6800/
project = demoو سپس:
scrapyd-deploy local
scrapyd-deploy production
scrapyd-deploy <target> -p <project>نکته: در محیط production اغلب نیاز به کانفیگ reverse proxy، TLS و احراز هویت دارید که بعداً توضیح داده خواهد شد.
کنترل اسپایدرها: گزینهها
برای کنترل و زمانبندی اسپایدرها سه مسیر معمول وجود دارد:
- استفاده مستقیم از Scrapyd JSON API (با HTTP requests / curl).
- استفاده از wrapper پایتون: python-scrapyd-api.
- استفاده از داشبورد مدیریتی (مثلاً ScrapeOps یا داشبوردهای متنباز) برای مدیریت متمرکز.
Scrapyd JSON API — مثال و نقاط مهم
مثال ساده برای گرفتن وضعیت daemon:
curl http://localhost:6800/daemonstatus.json
{ "status": "ok", "running": "0", "pending": "0", "finished": "0", "node_name": "MY_SERVER" }انتهای API مهم:
- daemonstatus.json — وضعیت سرور.
- addversion.json — افزودن ورژن پروژه.
- schedule.json — افزودن job به صف داخلی Scrapyd.
- cancel.json — لغو job (running یا pending).
- listprojects.json, listversions.json, listspiders.json, listjobs.json — اطلاعات مدیریت.
- delversion.json, delproject.json — حذف ورژنها یا پروژه.
نکتهٔ مهم: endpoint schedule.json صرفاً job را به صف داخلی Scrapyd اضافه میکند؛ این API برای زمانبندی زمانی (مثلاً اجرای در فلان تاریخ) طراحی نشده است. برای برنامهریزی زمانی نیاز به scheduler بیرونی (cron، ابزار مدیریت یا داشبوردی مثل ScrapeOps) دارید.
python-scrapyd-api: نمونه کد و توضیح
این کتابخانه یک wrapper ساده اطراف API فراهم میکند. نصب:
pip install python-scrapyd-apiنمونه استفاده پایه:
from scrapyd_api import ScrapydAPI
scrapyd = ScrapydAPI('http://localhost:6800')توضیح: ورودی به سازنده آدرس سرور Scrapyd است و خروجی یک شی حاوی متدهای مفید برای فراخوانی API است.
# وضعیت daemon
scrapyd.daemon_status()
# خروجی: dict شامل keys مانند 'running', 'pending', 'finished', 'node_name'توضیح: این متد وضعیت کلی سرور را برمیگرداند. خروجی برای مانیتورینگ سلامت سرور مفید است.
# فهرست پروژهها
scrapyd.list_projects()
# خروجی: لیستی از نام پروژهها، مثلاً ['demo', 'quotes_project']توضیح: برای دیدن پروژههای آپلود شده کاربرد دارد.
# فهرست اسپایدرهای یک پروژه
scrapyd.list_spiders('project_name')
# خروجی: ['spider1', 'spider2']توضیح: نام اسپایدرها را میگیرد و برای نمایش در UI یا اجرای انتخابی استفاده میشود.
# اجرای یک اسپایدر (برمیگرداند job_id)
job_id = scrapyd.schedule('project_name', 'spider_name')
# با ارسال settings دلخواه
settings = {'DOWNLOAD_DELAY': 2}
job_id = scrapyd.schedule('project_name', 'spider_name', settings=settings)توضیح ورودی/خروجی: ورودیها نام پروژه، نام اسپایدر و اختیاری دیکشنری settings هستند. خروجی یک شناسهٔ یکتای job است که برای پیگیری وضعیت یا لغو لازم است.
# لغو job
prev_state = scrapyd.cancel('project_name', job_id)
# بررسی وضعیت job
state = scrapyd.job_status('project_name', job_id) # 'running', 'pending', 'finished' یا '' برای نامشخصنکته: تابع cancel مقدار وضعیت قبلی job را برمیگرداند و بررسی نهایی با job_status انجام شود.
ملاحظات عملی دربارهٔ زمانبندی و پایداری
چند نکته عملی که در محیط تولید باید رعایت کنید:
- schedule.json job را در صف قرار میدهد؛ اگر نیاز به اجرای زمانبندی دقیق دارید از cron، Airflow، یا داشبوردهایی که scheduling دارند استفاده کنید.
- jobها باید idempotent باشند تا در حالت ریتری یا اجرای مجدد، دیتابیس یا مقصد داده تکراری نشود.
- از retry منطقی برای شکستهای موقت استفاده کنید و محدودیت تعداد تلاشها را ست کنید.
- منابع سرور (CPU/Memory) و concurrency را در settings پروژه کنترل کنید تا سرور Scrapyd اشباع نشود.
- لاگها را بهصورت متمرکز جمعآوری کنید تا Debug کردن در تولید سادهتر شود.
داشبوردها و ابزار مدیریت
API ساده است اما برای مدیریت چند سرور و پایپلاین کامل معمولاً از داشبورد استفاده میشود. مزایا:
- دید متمرکز روی jobs و سرورها.
- قابلیت زمانبندی دورهای و اعلانها.
- نمایش گرافها و کیفیت داده (در برخی ابزارها).
معایب: بعضی ابزارها نیاز به دسترسی عمومی به Scrapyd دارند که باید با احتیاط امنیتی انجام شود.
ادغام با ScrapeOps — مراحل عملی
ادغام معمولی شامل دو مرحله است: نصب extension برای ارسال لاگ و متریکها و سپس اضافه کردن سرور Scrapyd در داشبورد ScrapeOps.
مرحله ۱: نصب ScrapeOps logger extension
نصب بسته پایتون:
pip install scrapeops-scrapyافزودن سه خط به settings.py پروژه:
# 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,
}توضیح:
- SCRAPEOPS_API_KEY — کلید احراز هویت برای ارسال دادهها به داشبورد.
- EXTENSIONS — اکستنشن ScrapeOps که متریکها و لاگها را ارسال میکند.
- DOWNLOADER_MIDDLEWARES — جایگزینی middleware ریتری برای داشتن کنترل بهتر روی تلاشها و متریکها.
مرحله ۲: اتصال سرور Scrapyd و نکات امنیتی
برای اینکه سرویس مدیریتی بتواند با Scrapyd شما ارتباط برقرار کند، سرور باید از بیرون قابل دسترسی باشد (یا از طریق VPN / تونل امن). دو مسیر: نصب خودکار یا دستیِ راهاندازی دسترسی.
# مثال نصب خودکار (Ubuntu)
wget -O scrapeops_setup.sh "https://.../scrapeops_setup.sh"; bash scrapeops_setup.shدر حالت دستی معمولاً مراحل زیر انجام میشود:
- اجازه دادن به SSH:
sudo ufw allow ssh - باز کردن دسترسی برای IP مشخص (مثال):
sudo ufw allow from 46.101.44.87 to any port 443,80 proto tcp - فعالسازی فایروال:
sudo ufw enable sudo ufw status - نصب و کانفیگ nginx بهعنوان reverse proxy و فوروارد به Scrapyd:
sudo apt-get install nginx -y# در بلاک location فایل کانفیگ nginx
proxy_pass http://localhost:6800/;
proxy_set_header X-Forwarded-Proto http;نکات امنیتی مهم:
- از HTTPS (TLS) استفاده کنید و ترافیک را رمزنگاری نمایید.
- دسترسی را با فایروال محدود کنید (فقط IPهای مجاز).
- در صورت امکان از احراز هویت، VPN یا تونل داخلی برای دسترسی به Scrapyd استفاده کنید.
- لاگها و متریکها را برای تشخیص رفتار غیرعادی نگه دارید.
خلاصه و توصیههای عملی
در انتها چند توصیه عملی برای انتقال اسکریپرها به محیط تولید:
- پروژهها را با scrapyd-client بستهبندی و deploy کنید و نام ورژنها را مدیریت کنید.
- برای کنترل و automation از python-scrapyd-api یا یک داشبورد استفاده کنید؛ برای زمانبندی واقعی، از cron/Airflow/داشبوردهای scheduling بهره ببرید.
- jobs را idempotent و لاگگذاری را متمرکز کنید تا بازگردانی و دیباگ آسان شود.
- امنیت را جدی بگیرید: TLS، محدودیت IP، ریورسپروکسی و مانیتورینگ.
- قبل از اجرای در production، روی سرور staging تست بار و concurrency انجام دهید.
با دنبال کردن این مراحل و رعایت نکات بالا میتوانید جریان قابل اتکا و امنی برای وب اسکریپینگ با Scrapy و Scrapyd بسازید.





