خانه/مقالات/استقرار و زمان‌بندی اسکریپینگ با Scrapy
برنامه نویسی
داده‌کاوی
پروکسی و چرخش IP
برگشت به صفحه مقاله ها
استقرار و زمان‌بندی اسکریپینگ با Scrapy

استقرار و زمان‌بندی اسکریپینگ با Scrapy

این مقاله مرحله‌به‌مرحله نشان می‌دهد چگونه پروژه‌های Scrapy را برای اجرا در سرور آماده، مانیتور و زمان‌بندی کنید؛ تنظیم ScrapeOps، ساخت requirements، استقرار روی VPS (مثل Digital Ocean)، کلون کردن ریپازیتوری، مدیریت خطاها و ذخیرهٔ خروجی‌ها در PostgreSQL همراه با مثال‌های کد و نکات امنیتی توضیح داده شده‌اند.
آسان اسکریپ
آسان اسکریپ
1404-12-11

مقدمه

در این مقاله به‌صورت عملی و مرحله‌به‌مرحله یاد می‌گیریم چطور یک پروژه Scrapy را برای اجرا در محیط سرور آماده کنیم، آن را مانیتور و هشداردهی کنیم، به‌صورت برنامه‌ریزی‌شده اجرا نماییم و خروجی‌ها را در یک دیتابیس PostgreSQL ذخیره کنیم. مخاطب این راهنما توسعه‌دهنده پایتون با سطح متوسط است؛ پس علاوه بر دستورالعمل‌ها مثال‌های کد، نکات امنیتی، و روش‌های رفع خطا را هم می‌بینید.

چرا مانیتورینگ و استقرار مهم است

اسکریپینگ در مقیاس تولید بدون مانیتورینگ قابل اعتماد و راه‌اندازی مناسب به‌سختی پایدار می‌ماند. مانیتورینگ به شما کمک می‌کند خطاها، افت نرخ موفقیت، یا بلاک‌شدن آی‌پی را زود تشخیص دهید و زمان‌بندی (scheduling) تضمین می‌کند داده‌هایتان به‌روز باقی بمانند.

نصب افزونه مانیتورینگ (ScrapeOps)

برای ارسال آمار اجرای اسپایدرها و دریافت داشبورد و آلارتها از افزونه‌هایی مثل ScrapeOps استفاده می‌کنیم. ابتدا بسته مربوطه را نصب کنید:

pip install scrapeops-scrapy

در ادامه، مقداردهی در settings.py. به‌جای قرار دادن کلید به‌صورت صریح در فایل، بهتر است آن را از متغیر محیطی بخوانید:

import os

# گرفتن کلید از متغیر محیطی برای امنیت
SCRAPEOPS_API_KEY = os.getenv('SCRAPEOPS_API_KEY')

# فعال کردن افزونه
EXTENSIONS = {
    'scrapeops_scrapy.extension.ScrapeOpsMonitor': 500,
}

# بروزرسانی middleware های retry
DOWNLOADER_MIDDLEWARES = {
    'scrapeops_scrapy.middleware.retry.RetryMiddleware': 550,
    'scrapy.downloadermiddlewares.retry.RetryMiddleware': None,
}

توضیح: SCRAPEOPS_API_KEY ورودی است از محیط؛ EXTENSIONS افزونهٔ مانیتورینگ را ثبت می‌کند و در DOWNLOADER_MIDDLEWARES جایگزینی middleware پیش‌فرض retry انجام می‌شود تا آمار دقیق به ScrapeOps ارسال شود.

آماده‌سازی پروژه برای استقرار

یک فایل requirements.txt درست کنید تا سرور بتواند وابستگی‌ها را نصب کند. نمونه‌ای از محتوای این فایل:

scrapeops-scrapy==0.4.6
Scrapy==2.6.1
scrapy-proxy-pool==0.1.9
scrapy-user-agents==0.1.1
psycopg2-binary==2.9.6
SQLAlchemy==1.4.0

اگر پروژهٔ شما بسته‌های بیشتری دارد می‌توانید از محیط مجازی محلی خود خروجی بگیرید:

pip freeze > requirements.txt

نکات عملی:

  • همیشه از virtualenv/venv استفاده کنید تا وابستگی‌ها ایزوله بمانند.
  • ورژن‌ها را تعیین کنید تا تفاوت‌های محیط تولید و توسعه باعث خطا نشود.
  • کلیدها و پسوردها را در متغیرهای محیطی نگهدارید، نه در کد.

ایجاد سرور VPS (مثلاً Digital Ocean)

برای اجرا 24/7 به یک VPS نیاز دارید. تنظیمات پایه که پیشنهاد می‌شود:

  • سیستم عامل: Ubuntu 22.04
  • نوع: VPS کوچک با SSD (برای شروع اکثر پروژه‌ها کفایت می‌کند)
  • ترجیحاً با SSH Key به سرور وصل شوید؛ استفاده از رمز عبور ساده ریسک امنیتی دارد.

در سرور باید کاربر مجزا برای اجرای وظایف ایجاد کنید، و وابستگی‌ها را داخل یک محیط مجازی نصب کنید. اگر با ابزارهایی مانند ScrapeOps کار می‌کنید، معمولاً فرآیند نصب و کاربر جدید و کلید‌ها را خود سرویس یا اسکریپت نصب انجام می‌دهد.

اتصال سرور به ScrapeOps و نحوهٔ کلون کردن پروژه

به‌جای SSH و اجرای دستی git clone می‌توانید سرور را در داشبورد ScrapeOps اضافه کنید و از آنجا مخزن گیت‌هاب را کلون کنید. مراحل کلی:

  1. در داشبورد سرور را اضافه کنید و IP را وارد کنید.
  2. در کنسول تحت وب دستور wget/اسکریپت نصب را اجرا کنید تا کاربر و کلیدها تنظیم شوند.
  3. از گزینهٔ Clone Repository در داشبورد استفاده کنید و آدرس مخزن و نام شاخه را وارد کنید.

اگر Clone با خطا مواجه شد، پیام خطا را در صفحهٔ خطاها ببینید. خطاهای رایج:

  • عدم وجود پکیج‌های مورد نیاز در requirements.txt
  • نام شاخه اشتباه
  • دسترسی نداشتن به مخزن خصوصی (نیاز به دادن دسترسی)

اسکریپت نصب و کارهایی که به‌طور خودکار انجام می‌شود

معمولاً اسکریپت نصب مراحل زیر را انجام می‌دهد:

  1. ایجاد و فعال‌سازی virtualenv
  2. نصب پکیج‌های requirements.txt
  3. اجرای scrapy list برای یافتن اسپایدرها

اگر می‌خواهید اسکریپت نصب را بررسی یا شخصی‌سازی کنید، مطمئن شوید که تنظیمات مربوط به محیط و متغیرهای کلیدی قبل از اجرا مقداردهی شده‌اند.

اجرای محلی و دستی اسپایدر

برای اجرای دستی از سرور یا محلی می‌توانید از دستور زیر استفاده کنید:

scrapy crawl myspider

این دستور ورودی: نام اسپایدر (myspider)؛ خروجی: اجرای اسپایدر و تولید آیتم‌ها/فایل‌ها یا ارسال به پایپلاین‌ها. اگر از ScrapeOps استفاده می‌کنید، افزونه آمار اجرای این job را به داشبورد می‌فرستد.

زمان‌بندی (Scheduling) و نکات مربوط به کرون

برای اجرای دوره‌ای، ScrapeOps از مکانیزمی استفاده می‌کند که در نهایت یک کرونjob روی سرور ثبت می‌کند؛ نکات مهم:

  • زمان‌ها معمولاً بر اساس UTC ذخیره و اجرا می‌شوند؛ پس اختلاف ساعت محلی را در نظر بگیرید.
  • برای جلوگیری از تداخل اجراها، مطمئن شوید که اجرای قبلی کامل شده یا از قفل‌گذاری (lock file / database lock) استفاده کنید.
  • در صورت نیاز به اجرای موازی، محدودیت‌های سرور و نرخ درخواست‌ها را ارزیابی کنید.

ذخیرهٔ داده‌ها در PostgreSQL (Digital Ocean Postgres)

یکی از گزینه‌های معمول ذخیره‌سازی داده، گذاشتن خروجی در یک دیتابیس PostgreSQL است. در ادامه یک نمونه پایپلاین ساده با استفاده از psycopg2 و SQLAlchemy آورده شده است. این مثال ورودی: آیتم‌های Scrapy؛ خروجی: ردیف‌های درج‌شده در جدول postgres.

# pipelines.py
import os
from sqlalchemy import create_engine, Table, Column, Integer, String, MetaData
from sqlalchemy.exc import SQLAlchemyError

DB_URL = os.getenv('DATABASE_URL')  # example: postgres://user:pass@host:5432/dbname

class PostgresPipeline:
    def __init__(self):
        if not DB_URL:
            raise RuntimeError('DATABASE_URL environment variable not set')
        self.engine = create_engine(DB_URL)
        self.metadata = MetaData()
        # تعریف سادهٔ جدول؛ در پروژهٔ واقعی از migrations استفاده کنید
        self.items_table = Table('scraped_items', self.metadata,
                                 Column('id', Integer, primary_key=True),
                                 Column('title', String),
                                 Column('url', String))
        self.metadata.create_all(self.engine)

    def open_spider(self, spider):
        self.conn = self.engine.connect()

    def close_spider(self, spider):
        self.conn.close()

    def process_item(self, item, spider):
        try:
            ins = self.items_table.insert().values(title=item.get('title'), url=item.get('url'))
            self.conn.execute(ins)
        except SQLAlchemyError as e:
            spider.logger.error('DB insert error: %s', e)
        return item

توضیح خط‌به‌خط:

  • خط اول DB_URL را از متغیر محیطی می‌خواند تا اطلاعات حساس در کد نباشد.
  • create_engine اتصال را می‌سازد و متادیتا برای تعریف جدول استفاده می‌شود.
  • process_item برای هر آیتم اجرا می‌شود و آن را در جدول درج می‌کند؛ خطاها با لاگ ثبت می‌شوند.

نکات عملی برای دیتابیس:

  • از pooling و تایم‌اوت مناسب استفاده کنید تا اتصال‌ها هدر نروند.
  • برای حجم بالا از bulk inserts یا صف (queue) مانند RabbitMQ/Redis استفاده کنید.
  • مهاجرت شمای دیتابیس را با ابزارهایی مثل Alembic مدیریت کنید.

مدیریت خطاها و پایداری

برای داشتن یک استقرار قابل اطمینان توجه کنید به:

  • Retry منطقی با backoff برای پاسخ‌های ناموفق
  • Timeout مناسب برای درخواست‌ها
  • Rate limiting یا download delay برای جلوگیری از بلاک شدن
  • استفاده از پراکسی‌ها و گردش User-Agent برای کاهش ریسک بلاک
  • لاگ‌گیری ساختارمند و ارسال لاگ مهم به مانیتورینگ

امنیت و بهترین روش‌ها

چند توصیه امنیتی که اغلب نادیده گرفته می‌شود:

  • هرگز کلیدها، پسوردها یا URL های خصوصی را در ریپازیتوری عمومی قرار ندهید.
  • استفاده از SSH key به‌جای پسورد برای دسترسی به سرور امن‌تر است.
  • برای مخازن خصوصی دسترسی محدود و حساب سرویس جداگانه تعریف کنید.
  • محدود کردن دسترسی‌ها (firewall، منبع مجاز برای اتصال به دیتابیس).

عیب‌یابی متداول

خطاهای رایج و راه‌حل سریع:

  • خطای نصب پکیج‌ها: خروجی اسکریپت نصب را بخوانید و نام پکیج یا نسخهٔ موردنیاز را در requirements.txt اصلاح کنید.
  • عدم نمایش اسپایدرها بعد از کلون: بررسی کنید که پروژه یک ساختار Scrapy صحیح دارد (وجود scrapy.cfg و پوشه پروژه).
  • اجرای همزمان زیاد باعث خطاهای DB یا منابع می‌شود: نرخ و concurrency را کاهش دهید یا منابع سرور را زیاد کنید.

جمع‌بندی

برای استقرار و زمان‌بندی اسکریپینگ با Scrapy، چهار مرحلهٔ کلیدی وجود دارد: آماده‌سازی پروژه (requirements و تنظیمات)، راه‌اندازی سرور امن، اتصال و کلون از داشبورد مانیتورینگ، و در نهایت زمان‌بندی اجراها و ذخیرهٔ داده‌ها به‌صورت مطمئن در دیتابیس. رعایت نکات امنیتی، استفاده از متغیرهای محیطی برای کلیدها، و مانیتورینگ مستمر باعث می‌شود اسکریپ‌ها پایدار و قابل اعتماد اجرا شوند.

اگر زمان‌بندی و اجرای اتوماتیک برایتان اهمیت دارد، بهتر است از قفلینگ اجرا، بررسی وضعیت قبل از شروع job، و هشدارهای آنی در صورت خطا استفاده کنید تا از اجرای موازی یا از دست رفتن داده جلوگیری شود.

مقاله‌های مرتبط