ProxynetProxynet

وب اسکرپینگ و خزش وب: تفاوت در چیست؟

تاریخ انتشار:

15 دقیقه مطالعه

Acar Diveroli
نویسنده: Acar Diveroli
در چپ کارت‌های صفحه با پیوندهای میانشان، در راست فیلدهای یک صفحه که در ردیف‌ها ریخته می‌شوند، در میان نشان VS؛ جدول آبی است.

یک تیم فروشگاه اینترنتی هر صبح قیمت‌های یک رقیب را از فهرستی شامل چند صد URL محصول جمع‌آوری می‌کند. یک ماه، رقیب دسته تازه‌ای باز می‌کند. محصولات این دسته در فهرست نیستند، پس هرگز به گزارش نمی‌رسند و تا چند هفته کسی متوجه نمی‌شود. اسکرپر سریع‌تر هم کمکی نمی‌کرد. آنچه کم بود گامی بود که صفحه‌های دسته را بپیماید و آدرس‌های تازه را پیدا کند و درست همین‌جاست که خزش وب (web crawling) تمام می‌شود و وب اسکرپینگ (web scraping) آغاز می‌شود.

این نوشته وب اسکرپینگ و خزش وب را در شش محور مقایسه می‌کند: ورودی، خروجی، شرط توقف، حذف موارد تکراری، سرعت و robots.txt. توضیح می‌دهد خزنده کجا متوقف می‌شود و این دو کار چگونه در یک خط لوله به هم می‌پیوندند و سپس Spider و CrawlSpider را در Scrapy با کدی که خودمان اجرا کرده‌ایم نشان می‌دهد.

خزش وب چه می‌کند و وب اسکرپینگ چه می‌کند؟

خزش وب به این پرسش پاسخ می‌دهد: «به کجا می‌توانم بروم؟». خزنده یک صفحه را دریافت می‌کند، پیوندهای تازه‌ای را که در آن می‌یابد در صف می‌گذارد و این کار را تکرار می‌کند تا قاعده‌ای متوقفش کند. نتیجه، نقشه‌ای از صفحه‌های موجود است. کارهای خزنده و پروکسی‌هایی که پشت آن‌ها کار می‌کنند در صفحه خزنده وب ما آمده است.

وب اسکرپینگ به این پرسش پاسخ می‌دهد: «در این صفحه چه هست؟». اسکرپر صفحه‌ای را که از قبل می‌شناسد باز می‌کند و بخش‌هایی را که یک انسان می‌خواند (نام، قیمت، تاریخ، SKU) به یک ردیف ساختاریافته تبدیل می‌کند. انتخاب روش، از Excel تا Python، در صفحه استخراج داده ما و در نوشته استخراج داده از وب‌سایت آمده است. این دو با هم اشتباه گرفته می‌شوند، چون بیشتر ابزارها هر دو کار را انجام می‌دهند.

وقتی یک صفحه به خزنده و اسکرپر می‌رسد چه اتفاقی می‌افتد؟

یک صفحه دسته از یک کتاب‌فروشی را به هر دو بدهید. خزنده پیوندهای آن را می‌خواند:

  1. مقدارهای <a href> را در منوی دسته‌ها و دکمه «بعدی» (next) جمع می‌کند.
  2. آدرس‌های نسبی را مطلق و نرمال‌سازی می‌کند تا دو شکل نوشتاری از یک آدرس به یک رشته تبدیل شوند.
  3. هر آدرس را با مجموعه آدرس‌هایی که پیش‌تر دیده است مقایسه می‌کند.
  4. آدرس‌های تازه‌ای را که از قاعده‌های دامنه و عمقش می‌گذرند به صف خزش (frontier) اضافه می‌کند؛ یعنی صف آدرس‌هایی که منتظر دریافت‌اند.

اسکرپر محتوای آن را می‌خواند:

  1. فیلدها را با انتخابگرها پیدا می‌کند (انتخابگر CSS یا XPath).
  2. نوع‌ها را بررسی می‌کند: قیمت عدد است و SKU خالی نیست.
  3. ردیف را با کمک یک کلید رکورد با ردیف‌های قبلی ادغام می‌کند.
  4. ردیف را در یک فایل یا پایگاه داده می‌نویسد.

خزش وب و وب اسکرپینگ: جدول مقایسه

محورخزش وبوب اسکرپینگ
ورودیچند URL آغازین و قاعده‌های دنبال کردن پیوندفهرستی از آدرس‌های صفحه‌های شناخته‌شده
خروجیفهرستی از آدرس‌ها یا مجموعه‌ای از صفحه‌های دانلودشدهردیف‌های ساختاریافته (CSV، JSON، جدول پایگاه داده)
شرط توقفصف خزش خالی می‌شود یا به محدودیت عمق، دامنه یا تعداد صفحه می‌رسدفهرست تمام می‌شود
واحد حذف تکرارURL یا اثر انگشت درخواست (request fingerprint)کلید رکورد (SKU، شناسه آگهی)
چه چیزی سرعت را محدود می‌کندتعداد درخواست‌های هم‌زمان به هر میزبان و قاعده‌های robots.txtمحدودیت نرخ مقصد و زمان تجزیه صفحه
رابطه با robots.txtبه خط‌های Disallow در مسیرهایی برمی‌خورد که خودش کشف می‌کندکل فهرست را می‌توان پیش از اجرا بررسی کرد
خطای رایجگونه‌های بی‌پایان URL، کشیده شدن به دامنه‌های دیگرقالب تغییریافته‌ای که فیلدهای خالی برمی‌گرداند

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

ربات موتور جست‌وجو و ربات قیمت: دو سر یک طیف

Googlebot در سر خزش ایستاده است. راهنمای How Search Works گوگل می‌گوید برخی صفحه‌ها از بازدیدهای قبلی شناخته شده‌اند، برخی دیگر از راه پیوندهای صفحه‌های شناخته‌شده پیدا می‌شوند و نقشه‌های سایت (sitemap) صفحه‌های بیشتری اضافه می‌کنند. یک الگوریتم تصمیم می‌گیرد کدام سایت‌ها خزش شوند، هر چند وقت یک بار و چند صفحه از هرکدام دریافت شود و خزنده وقتی سرور خطا برمی‌گرداند سرعتش را کم می‌کند. صفحه‌های تکراری بعداً، در مرحله ایندکس، زیر یک صفحه canonical گروه‌بندی می‌شوند. راهنمای بودجه خزش (crawl budget) گوگل بیشتر برای سایت‌هایی نوشته شده است که بیش از یک میلیون صفحه یکتا دارند و این صفحه‌ها تقریباً هر هفته تغییر می‌کنند، یا بیش از 10,000 صفحه دارند که هر روز تغییر می‌کنند.

ربات قیمت در سر اسکرپینگ ایستاده است. فهرست ثابتی از آدرس‌های محصول دارد، هیچ پیوندی را دنبال نمی‌کند و هر روز همان مجموعه ردیف‌ها را برمی‌گرداند.

بیشتر کارهای تجاری در میانه قرار می‌گیرند: یک خزش هفتگی در دسته‌ها محصولات تازه را پیدا می‌کند و یک اسکرپر روزانه قیمت‌ها را از فهرستی می‌خواند که خزش به‌روز نگه می‌دارد، همان‌طور که در رصد قیمت رقبا آمده است. اینکه سایت‌ها ربات‌های جست‌وجوی تأییدشده را چگونه از بقیه ترافیک جدا می‌کنند در تشخیص بات چگونه کار می‌کند و اسکرپر Cloudflare توضیح داده شده است.

خزنده در یک سایت کجا متوقف می‌شود؟

خزنده فهرستی ندارد که به پایانش برسد، پس قاعده‌ها تعیین می‌کنند تا کجا پیش برود:

  • صف خزش خالی است. همه آدرس‌های کشف‌شده دریافت شده‌اند و آدرس تازه‌ای پیدا نشده است.
  • محدودیت عمق. عمق تعداد پرش‌های پیوندی از URL آغازین را می‌شمارد. مقدار پیش‌فرض DEPTH_LIMIT در Scrapy برابر 0 است، یعنی بدون محدودیت.
  • محدودیت دامنه. allowed_domains خزنده را روی سایت مقصد و زیردامنه‌هایش نگه می‌دارد. از ⁦Scrapy 2.18⁩ به بعد، تغییر آن در میانه خزش اعمال می‌شود.
  • سقف صفحه. سقفی قطعی مانند CLOSESPIDER_PAGECOUNT اجرا را تمام می‌کند، هر اتفاق دیگری هم که بیفتد.

نرمال‌سازی URL تعیین می‌کند که صف خزش اصلاً روزی خالی شود یا نه. بخش 6 از ⁦RFC 3986⁩ گام‌ها را شرح می‌دهد: scheme و host را با حروف کوچک بنویسید، کاراکترهای رزرونشده‌ای (unreserved) را که به‌صورت percent-encoded آمده‌اند رمزگشایی کنید، بخش‌های . و .. را حذف کنید و پورت پیش‌فرض را کنار بگذارید؛ به این ترتیب http://example.com و http://example.com:80/ یک منبع‌اند. فراتر از این، خودتان تصمیم می‌گیرید کدام پارامترهای query اهمیت دارند: ترتیب مرتب‌سازی یا شناسه نشست (session ID) برای همان محتوا آدرس تازه‌ای می‌سازد.

برخی سایت‌ها بی‌پایان آدرس می‌سازند؛ مثلاً تقویمی با پیوند «ماه بعد» یا ترکیب‌های فیلتری که با هر کلیک چند برابر می‌شوند. بدون محدودیت عمق و سقف صفحه، خزنده هرگز از آن‌ها بیرون نمی‌آید. پیوندهای تله‌ای که عمداً گذاشته می‌شوند هم همین‌طور عمل می‌کنند (تله‌های هانی‌پات). نقشه سایتی که منتشر شده است اغلب فهرست آغازین بهتری از دنبال کردن پیوندهاست (چگونه نقشه سایت یک وب‌سایت را پیدا کنیم).

موارد تکراری را در کدام لایه حذف کنیم: URL یا رکورد؟

خزنده درخواست‌های تکراری را حذف می‌کند. DUPEFILTER_CLASS پیش‌فرض در Scrapy همان RFPDupeFilter است که اثر انگشت درخواست‌ها را مقایسه می‌کند تا یک صفحه در یک اجرا دو بار دانلود نشود.

اسکرپر رکوردهای تکراری را حذف می‌کند. یک محصول می‌تواند از دو آدرس برسد، از راه دسته‌اش و از راه صفحه حراج، و فیلتر URL هر دو را عبور می‌دهد. کلید باید از خود داده بیاید: SKU، کد محصول یا شناسه آگهی. به همین دلیل این ادعا که اسکرپینگ به حذف موارد تکراری نیازی ندارد نادرست است. ذخیره ردیف‌ها بر اساس کلید در SQLite را در صفحه‌بندی در وب اسکرپینگ نشان داده‌ایم.

اثر robots.txt و قاعده‌های نرخ درخواست بر خزنده چیست؟

⁦RFC 9309⁩ خزنده‌ها را کلاینت‌های خودکار می‌نامد و خزنده‌های موتور جست‌وجو را مثال می‌زند که پیوندها را به‌صورت بازگشتی می‌پیمایند (recursively traverse links)؛ همچنین می‌گوید قاعده‌های robots.txt نوعی مجوز دسترسی نیستند (not a form of access authorization). خزنده مشروع با این حال از آن‌ها پیروی می‌کند و نباید نسخه ذخیره‌شده (cache) فایل را بیش از 24 ساعت به کار ببرد، مگر اینکه فایل در دسترس نباشد. خزنده بیشتر به خط‌های Disallow برمی‌خورد، چون مدام وارد مسیرهای تازه می‌شود. نحو فایل و Crawl-delay در فایل robots.txt چیست آمده است.

سرعت به‌ازای هر میزبان با CONCURRENT_REQUESTS_PER_DOMAIN و DOWNLOAD_DELAY محدود می‌شود. مقدارهای پیش‌فرض این دو در کد Scrapy به ترتیب 8 و 0 هستند؛ فایل settings.py که scrapy startproject می‌سازد هر دو را روی 1 می‌گذارد و ROBOTSTXT_OBEY را روشن می‌کند که در پیش‌فرض‌های کد False است. انتخاب عدد مناسب در همروندی و موازی‌سازی در وب اسکرپینگ، تلاش دوباره پس از 429 در کدهای وضعیت HTTP در وب اسکرپینگ و پخش کردن درخواست‌ها میان چند آدرس IP در چرخاندن پروکسی در Python آمده است. خزش گسترده روی میزبان‌های زیاد با پروکسی چرخشی جور درمی‌آید؛ فهرست ثابت و کوتاه اغلب با پروکسی دیتاسنتر به‌خوبی اجرا می‌شود.

خزش و اسکرپینگ چگونه در یک خط لوله به هم می‌پیوندند؟

در یک پروژه واقعی، این دو کار مرحله‌های یک چرخه‌اند:

  1. کشف. آدرس‌های آغازین و مدخل‌های نقشه سایت وارد سیستم می‌شوند.
  2. صف خزش. یک صف آدرس‌ها را همراه با اولویت و برچسب عمق نگه می‌دارد.
  3. دانلود. درخواست‌ها با محدودیت نرخ برای هر میزبان فرستاده می‌شوند و در خطاهای موقت دوباره تلاش می‌شوند.
  4. تجزیه (parsing). هر صفحه رکوردهایی برای خروجی و پیوندهای تازه‌ای برای صف خزش تولید می‌کند.

صف را روی دیسک نگه دارید تا خزشی که قطع شده بتواند ادامه پیدا کند: Scrapy برای این کار از JOBDIR استفاده می‌کند و نسخه‌ای با SQLite در صفحه‌بندی در وب اسکرپینگ آمده است. Scrapy به‌طور پیش‌فرض به شیوه عمق‌اول (depth-first) خزش می‌کند، چون صف‌های پیش‌فرضش LIFO هستند؛ مقدار مثبت DEPTH_PRIORITY همراه با صف‌های FIFO آن را به سمت سطح‌اول (breadth-first) می‌برد.

تفاوت Spider و CrawlSpider در Scrapy چیست؟

scrapy.Spider از start_urls شروع می‌کند و برای هر پاسخ parse را فرا می‌خواند. فقط وقتی پیوندی را دنبال می‌کند که کد شما درخواست تازه‌ای yield کند؛ پس با یک فهرست ثابت، یک اسکرپر خالص است.

CrawlSpider دنبال کردن پیوندها را به rules منتقل می‌کند. هر Rule یک LinkExtractor را با یک callback اختیاری و یک پرچم follow جفت می‌کند. بخش Spiders در مستندات Scrapy مقدار پیش‌فرض را تعیین می‌کند: اگر callback برابر None باشد، follow به‌طور پیش‌فرض True است و در غیر این صورت False. قاعده‌ای که callback ندارد از میان صفحه‌ها عبور می‌کند؛ قاعده‌ای که callback دارد صفحه‌ها را تجزیه می‌کند و همان‌جا می‌ایستد. همان صفحه هشدار می‌دهد که درخواستی که خودتان درون یک CrawlSpider می‌سازید به callback صریح نیاز دارد؛ درخواست بدون callback دوباره از مسیر قاعده‌ها فرستاده می‌شود.

فایل زیر هر دو را روی سایتی اجرا می‌کند که برای تمرین اسکرپینگ ساخته شده است. به ⁦Scrapy 2.19⁩ نیاز دارد (منتشرشده در 10 سپتامبر 2026، با ⁦Python 3.10⁩ یا جدیدتر). نصب و middleware پروکسی در Scrapy چیست و چگونه با پروکسی استفاده می‌شود آمده است.

python
"""One practice site, two jobs: a list scraper and a rule-based crawler."""
import sys

import scrapy
from scrapy.crawler import CrawlerProcess
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule

POLITE = {
    "ROBOTSTXT_OBEY": True,  # a script run has no project settings.py, so set it here
    "CONCURRENT_REQUESTS_PER_DOMAIN": 2,
    "DOWNLOAD_DELAY": 1,
    "RETRY_TIMES": 2,  # RetryMiddleware: up to 2 retries on 429, 500/502/503/504 and timeouts
    "USER_AGENT": "ExampleCatalogBot/1.0 (+https://example.com/bot)",
}


def product(response):
    """The record: the UPC is its key, so two URLs for one book give one row."""
    return {
        "upc": response.xpath("//th[text()='UPC']/following-sibling::td/text()").get(),
        "title": response.css("div.product_main h1::text").get(),
        "price": response.css("div.product_main p.price_color::text").get(),
        "url": response.url,
    }


class ListSpider(scrapy.Spider):
    """Scraping: a known list of product URLs, no link following."""

    name = "list"
    custom_settings = POLITE
    start_urls = [
        "https://books.toscrape.com/catalogue/a-light-in-the-attic_1000/index.html",
        "https://books.toscrape.com/catalogue/tipping-the-velvet_999/index.html",
        "https://books.toscrape.com/catalogue/soumission_998/index.html",
    ]

    def parse(self, response):
        yield product(response)


class CatalogSpider(CrawlSpider):
    """Crawling: find product pages by following category and next-page links."""

    name = "catalog"
    allowed_domains = ["books.toscrape.com"]
    start_urls = ["https://books.toscrape.com/catalogue/category/books/poetry_23/index.html"]
    custom_settings = {**POLITE, "DEPTH_LIMIT": 3, "CLOSESPIDER_PAGECOUNT": 60}
    rules = (
        # No callback, so follow defaults to True: links on these pages are followed.
        Rule(LinkExtractor(restrict_css=("ul.nav-list", "li.next"))),
        # A callback, so follow defaults to False: product pages are parsed, not crawled.
        Rule(LinkExtractor(restrict_css="article.product_pod h3"), callback="parse_item"),
    )

    def parse_item(self, response):
        yield product(response)


if __name__ == "__main__":
    spider = CatalogSpider if sys.argv[1:] == ["catalog"] else ListSpider
    feed = {f"{spider.name}.jsonl": {"format": "jsonlines", "encoding": "utf-8"}}
    process = CrawlerProcess(settings={"FEEDS": feed})
    process.crawl(spider)
    process.start()

python spiders.py اسکرپر را اجرا می‌کند و python spiders.py catalog خزنده را. از بلوک __main__ استفاده می‌کنیم، چون scrapy runspider از فایلی که دو کلاس spider دارد فقط یکی را برمی‌دارد. برای پروکسی، نخست https_proxy=http://user:pass@pr.proxynet.io:8000 را در متغیرهای محیطی تنظیم کنید؛ HttpProxyMiddleware در Scrapy آن را می‌خواند.

نتیجه اجراها

هر دو را با ⁦Python 3.13⁩ و ⁦Scrapy 2.19.0⁩ اجرا کردیم، یک بار مستقیم و یک بار از طریق یک پروکسی آزمایشی محلی:

  • اسکرپر چهار درخواست فرستاد، یکی برای robots.txt (که 404 برگرداند، پس قاعده‌ای در کار نبود) و سه تا برای سه آدرس، و سه ردیف نوشت.
  • خزنده پس از 74 صفحه، نه 60، با finish_reason: closespider_pagecount و 56 کتاب یکتا بسته شد: درخواست‌هایی که پیش‌تر به downloader سپرده شده‌اند باز هم کامل می‌شوند، پس این سقف تقریبی است.
  • فیلتر موارد تکراری 867 درخواست را کنار گذاشت، چون هر صفحه دسته در منوی خود به هر 50 دسته پیوند می‌دهد.
  • با DEPTH_LIMIT برابر 1، خزنده 3,151 پیوند عمیق‌تر را نادیده گرفت، فقط 19 کتاب شعری را که صفحه آغازین به آن‌ها پیوند داده بود جمع کرد و وقتی صف خزشش خالی شد با finish_reason: finished به پایان رسید.
  • از طریق پروکسی، اسکرپر همان ردیف‌ها را برگرداند. با رمز عبور نادرست، پس از هر 407 دو بار دیگر تلاش شد و سپس Scrapy دست کشید.

کاربردها

  • رصد قیمت رقبا: فهرستی ثابت که هر روز اسکرپ می‌شود، به‌علاوه یک خزش هفتگی برای محصولات تازه (رصد قیمت رقبا).
  • پایش قیمت در مقیاس بزرگ: فروشگاه‌های زیاد که هرکدام با سرعت خودش خوانده می‌شود (پایش قیمت).
  • ممیزی سئوی سایت: پیدا کردن پیوندهای شکسته و صفحه‌های یتیم (orphan pages) خزش خالص است و خروجی آن آدرس‌ها و کدهای وضعیت است (پروکسی سئو).
  • حفاظت از برند: خزش یک مارکت‌پلیس آگهی‌های تازه را پیدا می‌کند و اسکرپر فروشنده و قیمت را می‌خواند (حفاظت از برند).
  • کاتالوگ‌های مبتنی بر JavaScript: خزش صفحه‌ها را پیدا می‌کند و مرورگر headless فقط صفحه‌هایی را رندر می‌کند که به آن نیاز دارند (صفحه‌های ایستا و پویا در وب اسکرپینگ).

اشتباه‌های رایج

  • خزش کل سایت برای کاری که فهرست ثابتی دارد. بی‌دلیل بار روی سایت می‌گذارد و به خط‌های Disallow بیشتری برمی‌خورد.
  • نادیده گرفتن نرمال‌سازی URL. همان صفحه با ترتیب متفاوت پارامترهای query بارها و بارها دانلود می‌شود.
  • follow=True روی قاعده‌ای که callback دارد، بدون محدودیت عمق. هر صفحه محصول به نقطه شروع تازه‌ای تبدیل می‌شود و خزش از راه پیوندهای محصولات مرتبط پخش می‌شود.
  • جا انداختن allowed_domains. یک پیوند به فروشگاه یک شریک تجاری کافی است تا خزنده از سایت مقصد بیرون برود.
  • دریافت robots.txt در هر درخواست، یا دیگر هرگز. یک بار برای هر میزبان کافی است؛ در اجراهای طولانی‌تر آن را پیش از گذشت 24 ساعت تازه کنید.
  • ردیف‌های بدون کلید رکورد. محصولی که از دو مسیر پیدا شده دو بار نوشته می‌شود.
  • فرستادن درخواست دست‌ساز با yield و بدون callback در یک CrawlSpider. این درخواست به‌جای رسیدن به parser شما دوباره از مسیر قاعده‌ها می‌گذرد.

راهنمای انتخاب

نیازپیشنهاد
فهرست آدرس‌های محصولم ثابت است و هر روز قیمت‌ها را می‌خوانمفقط یک اسکرپر (scrapy.Spider یا یک کلاینت HTTP)
محصولات تازه رقیب را هم می‌خواهمیک خزش هفتگی در دسته‌ها که آدرس اضافه می‌کند، به‌علاوه اسکرپر روزانه
برای پیدا کردن پیوندهای شکسته به همه صفحه‌های سایتم نیاز دارمیک خزنده خالص؛ خروجی آدرس‌ها و کدهای وضعیت است
می‌خواهم Scrapy پیوندها را بر اساس قاعده دنبال کندCrawlSpider با Rule و LinkExtractor، همیشه همراه با DEPTH_LIMIT و allowed_domains
سایت نقشه سایت منتشر می‌کنداز نقشه سایت شروع کنید؛ پیوندها را فقط برای بخش‌هایی دنبال کنید که در آن نیامده‌اند
خزشی که قطع می‌شود نباید از اول شروع شودصف ماندگار: JOBDIR در Scrapy یا یک جدول SQLite

پرسش‌های متداول

آیا خزش وب و وب اسکرپینگ یک چیزند؟

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

Googlebot خزنده است یا اسکرپر؟

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

تفاوت Spider و CrawlSpider در Scrapy چیست؟

Spider فقط پیوندهایی را دنبال می‌کند که کد شما درخواست می‌دهد و برای فهرست ثابت مناسب است. CrawlSpider پیوندها را از راه rules دنبال می‌کند: قاعده بدون callback به‌طور پیش‌فرض دنبال می‌کند و قاعده دارای callback به‌طور پیش‌فرض تجزیه می‌کند و دنبال نمی‌کند. درخواست‌هایی که خودتان yield می‌کنید به callback صریح نیاز دارند.

آیا خزنده باید از robots.txt پیروی کند؟

⁦RFC 9309⁩ می‌گوید این قاعده‌ها نوعی مجوز دسترسی نیستند، پس این فایل قفل نیست. خزنده مشروع با این حال از آن پیروی می‌کند، نرخ درخواست را پایین نگه می‌دارد و User-Agent صادقانه‌ای به کار می‌برد. پیامدهای حقوقی به کشور و شرایط هر مورد بستگی دارد (آیا اسکرپینگ وب قانونی است؟).

برای خزش و اسکرپینگ از کدام کتابخانه‌های Python استفاده می‌شود؟

Scrapy هر دو را پوشش می‌دهد: برای خزش، زمان‌بند (scheduler)، فیلتر موارد تکراری، بررسی robots.txt و محدودیت نرخ دارد و برای اسکرپینگ، انتخابگرها. برای یک فهرست کوتاه، Requests یا HTTPX همراه با BeautifulSoup یا lxml اغلب کافی است (مقایسه HTTPX، Requests و AIOHTTP).

آیا برای خزش به پروکسی نیاز دارید؟

خزنده درخواست‌های زیادی به یک میزبان می‌فرستد و سایت‌ها تعداد درخواست‌ها را به‌ازای هر IP محدود می‌کنند. پروکسی یک خزش گسترده را میان چند آدرس IP پخش می‌کند، اما هر میزبان همچنان باید درخواست‌ها را با نرخی مؤدبانه دریافت کند. برای خزش‌های بزرگ روی سایت‌های زیاد، پروکسی چرخشی به هر درخواست یا نشست یک خروجی متفاوت می‌دهد.

خلاصه

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

پرسش از ChatGPTپرسش از Claude