FA-TOOLS — Header Component

آموزش Scrapy برای crawl کردن سایت‌های بزرگ

رفیق برنامه‌نویس، اگه تا حالا با چالش جمع‌آوری داده از سایت‌های بزرگ و پیچیده دست و پنجه نرم کردی، می‌دونی که ابزارهای معمولی چقدر می‌تونن ناکارآمد باشن. اما یه خبر خوب دارم: Scrapy اینجاست تا بازی رو عوض کنه! این فریم‌ورک قدرتمند پایتون، بهت این امکان رو میده که با سرعتی باورنکردنی و دقتی مثال‌زدنی، داده‌ها رو از هر کجای وب شکار کنی و برای تجزیه و تحلیل آماده‌شون کنی. اگه دنبال ابزارهای بیشتر و کدهای آماده هستی، یه سر به فروشگاه ابزارهای ما بزن و ببین چیا داریم که می‌تونه کارتو راه بندازه!

💡 نقشه راه جامع Scrapy در یک نگاه 💡

اینجا یه خلاصه جمع و جور از چیزایی که قراره یاد بگیریم رو برات آوردم. یه جورایی roadmap پروژه‌ی بزرگ‌ت!

  • معرفی Scrapy: چرا این فریم‌ورک برای پروژه‌های بزرگ ضروریه؟
  • 🚀 نصب و راه‌اندازی: آماده‌سازی محیط کار
  • 🕷️ ساخت Spider: منطق اصلی خزیدن و استخراج داده‌ها
  • 🎯 Selectors (CSS/XPath): روش‌های دقیق انتخاب اطلاعات
  • 📦 Items & Pipelines: سازماندهی و ذخیره‌سازی داده‌های استخراجی
  • ⚙️ بهینه‌سازی برای مقیاس بزرگ: تنظیمات حیاتی برای کرالرهای حرفه‌ای
  • 🛠️ عیب‌یابی: پاسخ به مشکلات رایج و راه‌حل‌ها

با این راهنما، دیگه هیچ سایتی برای کرال کردن برات غریبه نیست!

Scrapy چیه و چرا برای سایت‌های بزرگ عالیه؟

آموزش Scrapy برای crawl کردن سایت‌های بزرگ — تصویر 2

Scrapy یه فریم‌ورک پایتون متن‌باز و فوق‌العاده سریع برای وب کرالینگ و اسکرپینگه. اسمش هم از “Scrape” و “Python” گرفته شده. اگه بخوام ساده بگم، Scrapy بهت کمک می‌کنه تا صفحات وب رو به صورت خودکار بازدید کنی، اطلاعات مورد نیازت رو از دل HTML بیرون بکشی و بعد اونارو توی فرمت‌های مختلف (مثل JSON، CSV یا حتی دیتابیس) ذخیره کنی.

حالا چرا Scrapy برای سایت‌های بزرگ عالیه؟ چون با یه عالمه قابلیت خفن مثل قابلیت اجرای همزمان درخواست‌ها (Concurrency)، مدیریت هوشمند Queue، سیستم پایپ‌لاین قدرتمند و پشتیبانی از Middlewares، عملاً یه ابزار تمام عیار برای پروژه‌‌ی بزرگیه. این یعنی می‌تونی باهاش هزاران صفحه رو در کمترین زمان ممکن کرال کنی، بدون اینکه سرور سایت مورد نظر رو اذیت کنی یا خودت تو مدیریت درخواست‌ها غرق بشی.

نصب و راه‌اندازی Scrapy

آموزش Scrapy برای crawl کردن سایت‌های بزرگ — تصویر 3

قبل از هر چیزی، باید Scrapy رو روی سیستمت نصب کنی. فرض می‌کنم پایتون و pip رو از قبل داری. اگه نه، اول اونا رو نصب کن!

گام اول: نصب Scrapy

ترمینال یا Command Prompt رو باز کن و دستور زیر رو بزن:

pip install Scrapy

اگه باگرفتن خطایی مثل “permission denied” مواجه شدی، احتمالا نیاز به دسترسی ادمین داری. توی لینوکس و مک می‌تونی از `sudo pip install Scrapy` استفاده کنی و توی ویندوز Command Prompt رو با “Run as administrator” باز کنی.

اولین پروژه‌ی Scrapy رو بسازیم

بعد از نصب موفقیت‌آمیز، حالا وقتشه اولین پروژت رو با Scrapy ایجاد کنی. یه فولدر برای پروژه‌هات در نظر بگیر و توی اون فولدر دستور زیر رو اجرا کن:

scrapy startproject my_crawler

این دستور یه ساختار فولدر استاندارد برای پروژت ایجاد می‌کنه. حالا وارد فولدر `my_crawler` شو:

cd my_crawler

Spiders: قلب تپنده Scrapy

“Spider” یا عنکبوت، جاییه که تمام منطق کرال کردن و استخراج دادها رو می‌نویسی. هر Spider مسئول کرال کردن یک دامنه یا گروهی از دامنه‌های مرتبط هست.

ساخت اولین Spider

برای ساخت یه Spider جدید، این دستور رو داخل فولدر اصلی پروژت (همون `my_crawler`) اجرا کن:

scrapy genspider quotes_spider quotes.toscrape.com

این دستور یه فایل جدید به اسم `quotes_spider.py` داخل فولدر `spiders` پروژت ایجاد می‌کنه. محتوای اون تقریبا شبیه اینه:

import scrapy

class QuotesSpider(scrapy.Spider):
    name = "quotes_spider"
    allowed_domains = ["quotes.toscrape.com"]
    start_urls = ["https://quotes.toscrape.com/page/1/"]

    def parse(self, response):
        # اینجا جاییه که باید داده‌ها رو استخراج کنی
        pass
  • `name`: یه اسم منحصر به فرد برای Spiderت.
  • `allowed_domains`: لیستی از دامنه‌هایی که Spider اجازه کرال کردنشون رو داره. Scrapy فقط لینک‌هایی که به این دامنه‌ها اشاره می‌کنن رو دنبال می‌کنه.
  • `start_urls`: لیستی از URLهایی که Spider کارش رو از اونا شروع می‌کنه.
  • `parse(self, response)`: این متد به صورت پیش‌فرض برای پردازش پاسخ (Response) هر درخواست HTTP فراخوانی میشه. تمام منطق استخراج داده اینجا پیاده‌سازی میشه.

انتخابگرها (Selectors): راهی برای شکار داده‌ها

وقتی Spider یه صفحه رو دانلود می‌کنه، محتوای HTML اون صفحه رو به متد `parse` می‌فرسته. حالا چطور باید از این HTML خام، اطلاعات مورد نظرت رو بیرون بکشی؟ اینجا Selectorها وارد میدون میشن. Scrapy از CSS Selectors و XPath برای انتخاب المان‌های HTML استفاده می‌کنه.

اگه با CSS کار کرده باشی، می‌دونی چقدر انتخابگرها راحتن. XPath هم یه زبان قدرتمند برای پیمایش در درخت DOM هست.

مثال استخراج داده

import scrapy

class QuotesSpider(scrapy.Spider):
    name = "quotes_spider"
    allowed_domains = ["quotes.toscrape.com"]
    start_urls = ["https://quotes.toscrape.com/page/1/"]

    def parse(self, response):
        # با استفاده از CSS selector تمام نقل قول‌ها رو انتخاب می‌کنیم
        for quote in response.css('div.quote'):
            yield {
                'text': quote.css('span.text::text').get(),
                'author': quote.css('small.author::text').get(),
                'tags': quote.css('div.tags a.tag::text').getall(),
            }

        # پیدا کردن لینک صفحه بعدی و ارسال درخواست جدید
        next_page = response.css('li.next a::attr(href)').get()
        if next_page is not None:
            yield response.follow(next_page, callback=self.parse)

توی کد بالا:

  • `response.css()`: از CSS Selector برای انتخاب المان‌ها استفاده می‌کنه.
  • `::text`: محتوای متنی المان رو برمی‌گردونه.
  • `::attr(href)`: مقدار یک ویژگی (attribute) رو برمی‌گردونه.
  • `.get()`: اولین نتیجه پیدا شده رو برمی‌گردونه.
  • `.getall()`: تمام نتایج پیدا شده رو به صورت لیست برمی‌گردونه.
  • `response.follow()`: برای ساخت یک درخواست جدید و دنبال کردن لینک‌ها استفاده میشه. این خیلی مهمه برای پیمایش صفحات.

جدول آموزشی: تفاوت CSS Selector و XPath

ویژگی توضیح
CSS Selector ابزار قدرتمند و شهودی برای انتخاب المان‌های HTML بر اساس تگ، کلاس، ID و ویژگی‌ها.
XPath زبان جامع‌تر برای پیمایش کامل درخت DOM. امکان انتخاب المان‌ها بر اساس متن، روابط والد-فرزندی و سایر معیارهای پیچیده.

انتخاب بین این دو به پیچیدگی ساختار سایت و نیاز شما بستگی دارد.

آیتم‌ها (Items): سازماندهی داده‌های استخراجی

برای اینکه داده‌های استخراج شده‌ات منظم و قابل مدیریت باشن، Scrapy یه مفهومی به اسم `Item` داره. Itemها مثل دیکشنری‌های پایتون عمل می‌کنن، اما با یه ساختار تعریف شده که باعث میشه کد خوندنی‌تر و باگ‌ها کمتر بشن.

تعریف یک Item

فایل `items.py` داخل پروژت رو باز کن و یه Item مثل این تعریف کن:

import scrapy

class QuoteItem(scrapy.Item):
    # تعریف فیلدهای آیتم شما اینجا
    text = scrapy.Field()
    author = scrapy.Field()
    tags = scrapy.Field()

استفاده از Item در Spider

حالا می‌تونی توی Spiderت به جای دیکشنری‌های خام، از این Item استفاده کنی:

import scrapy
from my_crawler.items import QuoteItem # وارد کردن آیتم

class QuotesSpider(scrapy.Spider):
    name = "quotes_spider"
    allowed_domains = ["quotes.toscrape.com"]
    start_urls = ["https://quotes.toscrape.com/page/1/"]

    def parse(self, response):
        for quote_div in response.css('div.quote'):
            quote = QuoteItem() # ساخت یک نمونه از آیتم
            quote['text'] = quote_div.css('span.text::text').get()
            quote['author'] = quote_div.css('small.author::text').get()
            quote['tags'] = quote_div.css('div.tags a.tag::text').getall()
            yield quote

        next_page = response.css('li.next a::attr(href)').get()
        if next_page is not None:
            yield response.follow(next_page, callback=self.parse)

پایپ‌لاین‌ها (Pipelines): پردازش و ذخیره داده‌ها

Itemها بعد از اینکه توسط Spider تولید میشن، از طریق Item Pipelineها عبور می‌کنن. Pipelineها مجموعه‌ای از کلاس‌ها هستن که هر کدوم یه وظیفه خاص مثل اعتبارسنجی داده، حذف داده‌های تکراری، یا ذخیره داده‌ها در دیتابیس رو انجام میدن. این مدل باعث میشه کداتون ماژولار و قابل نگهداری‌تر باشن.

ساخت یک Pipeline ساده (ذخیره در JSON)

فایل `pipelines.py` رو باز کن و این کد رو بهش اضافه کن:

import json

class JsonWriterPipeline:
    def open_spider(self, spider):
        self.file = open('quotes.json', 'w', encoding='utf-8')
        self.file.write("[n")

    def close_spider(self, spider):
        self.file.write("n]")
        self.file.close()

    def process_item(self, item, spider):
        line = json.dumps(dict(item), ensure_ascii=False) + ",n"
        self.file.write(line)
        return item

فعال‌سازی Pipeline

برای فعال کردن Pipeline، فایل `settings.py` رو باز کن و بخش `ITEM_PIPELINES` رو پیدا کن (اگه نیست، اضافه کن). سپس Pipeline خودت رو با یه عدد (اولویت) بهش اضافه کن:

ITEM_PIPELINES = {
    'my_crawler.pipelines.JsonWriterPipeline': 300, # عدد کمتر یعنی اولویت بالاتر
}

از این Pipeline می‌تونی برای کارهای دیگه هم استفاده کنی. مثلاً فیلدها رو پاکسازی کنی، داده‌ها رو نرمالایز کنی یا حتی به یه دیتابیس بفرستی. اگه با کدهای آماده پایتون آشنایی داشته باشی، می‌تونی Pipelineهای خیلی پیشرفته‌تری بنویسی.

تنظیمات پیشرفته برای Crawling در مقیاس بزرگ

کرال کردن سایت‌های بزرگ نیاز به تنظیمات دقیق داره تا هم کارایی کرالر بالا بره و هم به سرور سایت هدف آسیب نرسونه یا بلاک نشی. این تنظیمات رو باید توی فایل `settings.py` تغییر بدی.

مدیریت سرعت و درخواست‌ها

  • `ROBOTSTXT_OBEY = True` (پیشنهادی):

    این تنظیم Scrapy رو مجبور می‌کنه تا فایل `robots.txt` سایت رو بررسی کنه و صفحاتی که اجازه کرال ندارن رو رد کنه. این یه کار اخلاقیه و از بلاک شدنتم جلوگیری می‌کنه.

  • `CONCURRENT_REQUESTS = 16` (پیش‌فرض 16):

    تعداد درخواست‌های همزمانی که Scrapy می‌تونه به یک دامنه ارسال کنه. برای سایت‌های بزرگ، اگه خیلی زیادش کنی ممکنه بلاک بشی. می‌تونی با یه عدد پایین‌تر شروع کنی (مثلاً 4 یا 8) و کم‌کم زیادش کنی.

  • `DOWNLOAD_DELAY = 1` (پیش‌فرض 0):

    مقدار تاخیر (بر حسب ثانیه) بین درخواست‌های متوالی به یک دامنه. اگه اینو 0 بذاری، Scrapy با تمام سرعت حمله می‌کنه و احتمال بلاک شدنت بالاست. با یه مقدار معقول مثل 1 تا 3 ثانیه شروع کن.

  • `AUTOTHROTTLE_ENABLED = True` (پیشنهادی):

    این قابلیت به Scrapy اجازه میده سرعت کرال کردن رو به صورت خودکار با توجه به فشار روی سرور سایت هدف تنظیم کنه. این یه راحلی هوشمندانه برای جلوگیری از بلاک شدن و آسیب به سروره.

شناسایی خودت به عنوان کاربر

  • `USER_AGENT`:

    به صورت پیش‌فرض Scrapy خودش رو به عنوان یه “Scrapy bot” معرفی می‌کنه. خیلی از سایت‌ها ربات‌ها رو بلاک می‌کنن. یه `User-Agent` معتبر (مثلاً یه مرورگر واقعی) بهت کمک می‌کنه:

    USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
            

مدیریت سشن و کوکی‌ها (Sessions & Cookies)

بعضی سایت‌ها برای ردیابی کاربرها یا برای دسترسی به محتوای خاص، نیاز به سشن و کوکی دارن. Scrapy به صورت خودکار کوکی‌ها رو مدیریت می‌کنه، ولی اگه نیاز به مدیریت پیشرفته‌تری داری، می‌تونی از Middlewares استفاده کنی یا تنظیم `COOKIES_ENABLED` رو کنترل کنی.

COOKIES_ENABLED = True # به صورت پیش‌فرض فعال است

Proxyها و چرخاندن آن‌ها

برای کرال کردن سایت‌های خیلی بزرگ یا سایت‌هایی که محافظت شدیدی دارن، ممکنه نیاز داشته باشی از Proxy استفاده کنی تا آدرس IP خودت رو مخفی کنی و از بلاک شدن جلوگیری کنی. می‌تونی یه لیست از Proxyها رو توی یه Middleware استفاده کنی و اونا رو بین درخواست‌ها بچرخونی. این کار پیچیده‌تره و نیاز به کدهای آماده و اسنیپت‌های خاصی داره که باید بنویسی.

عیب‌یابی سریع (Troubleshooting)

تو دنیای وب کرالینگ، مشکل پیش اومدن طبیعیه. اینجا چندتا از مشکلات رایج و راه‌حل‌هاشون رو برات آوردم:

  • کرالر بلاک میشه (HTTP 403/429):

    راه‌حل: `DOWNLOAD_DELAY` رو افزایش بده، `AUTOTHROTTLE_ENABLED` رو `True` کن، `USER_AGENT` رو به یه مرورگر واقعی تغییر بده، و در صورت نیاز از Proxy Rotation استفاده کن.

  • داده‌ای استخراج نمیشه (نتایج خالی):

    راه‌حل: اول با `scrapy shell ‘URL’` صفحه‌رو باز کن و Selectorهات رو تست کن. مطمئن شو که Selectorهات درستن و محتوای مورد نظرت با جاوااسکریپت لود نمیشه (Scrapy به صورت پیش‌فرض جاوااسکریپت رو رندر نمی‌کنه).

  • خطای `DNS lookup failed`:

    راه‌حل: مطمئن شو `allowed_domains` رو درست نوشتی و URLها توی `start_urls` یا لینک‌های `follow` معتبر هستن.

  • مصرف حافظه بالا:

    راه‌حل: مطمئن شو که در `parse` متد، `yield` میکنی نه `return`. Scrapy برای مدیریت حافظه به `yield` نیاز داره. اگه داده‌های خیلی بزرگی داری، میتونی از Pipelineها برای ذخیره زودتر داده‌ها استفاده کنی.

  • مشکلات نصب `lxml` یا `Twisted` (وابستگی‌های Scrapy):

    راه‌حل: این مشکل معمولا توی ویندوز پیش میاد. سعی کن نسخه‌های از پیش کامپایل شده (wheel files) رو برای این پکیج‌ها نصب کنی یا برای پایتون 3.9 به بالا، پکیج `build-essential` (لینوکس) یا Xcode Command Line Tools (مک) رو نصب کنی. توی اسنیپت‌های پایتون ما راهنماهای بیشتری برای رفع این مشکلات داریم.

نیاز به کمک داریَ؟ اگه با مشکلی روبرو شدی که اینجا بهش اشاره نشده، می‌تونی با کارشناس‌های ما تماس بگیری و کمک بگیری.

تماس: 09202232789

جمع‌بندی

Scrapy یه ابزار قدرتمند و انعطاف‌پذیره که بهت این امکان رو میده تا با خیال راحت و کارآمد، سایت‌های بزرگ رو کرال کنی و داده‌های مورد نیازت رو استخراج کنی. با یادگیری مفاهیم اصلی مثل Spiderها، Selectorها، Itemها و Pipelineها، و همچنین تنظیمات پیشرفته، می‌تونی کرالرهای حرفه‌ای و پایداری بسازی. حالا وقتشه که آستین بالا بزنی و دنیای داده‌ها رو به تسخیر خودت دربیاری! اگه با وردپرس یا HTML هم سروکار داری، حتماً یه نگاهی به بقیه اسنیپت‌های ما بنداز.

Table of Contents

آخرین نوشته‌ها