با شناسایی آغاز کنید، نه با زور بازو
بدترین اسکرپرها کورکورانه میپیمایند. آنها سایت را زیر فشار میگذارند، اعلانهای crawl-delay را نادیده میگیرند، هر مسیری را در جستوجوی داده زیر و رو میکنند و با تغییر ساختار حتی به اندازهی یک نام کلاس از کار میافتند. بهترین اسکرپرها با خواندن خودِ سایت آغاز میکنند.
هر وبسایت یک قرارداد را در سه جا منتشر میکند: robots.txt (سیاست پیمایش)، نقشههای سایت (آنچه خودِ سایت شایستهی نمایهسازی میداند) و گراف پیوندها (چگونگی اتصال واقعی صفحهها به یکدیگر). خواندنِ نخستِ اینها پیش از نوشتن حتی یک خط کد اسکرپینگ به سه پرسش پاسخ میدهد:
- آیا این سایت قابل اسکرپ است؟ robots.txt چه چیزی را مجاز میداند و با چه سرعتی؟
- داده کجاست؟ نقشههای سایت چه چیزی را آشکار میکنند؟
- ساختار سایت چگونه است؟ توپولوژی پیوندها چه شکلی دارد؟
این همان کاری است که sitemapper انجام میدهد.
کشف منفعل: robots.txt + نقشههای سایت
discover() فایل robots.txt و هر نقشهی سایتی را که بتواند بیابد دریافت میکند —
از جمله دستورهای Sitemap:، شاخصهای نقشهی سایت که به زیرنقشهها اشاره میکنند و
فایلهای فشردهشده با gzip — بدون آنکه حتی یک صفحهی HTML را بپیماید:
from sitemapper import discover
info = discover("https://www.python.org")
print(info.summary())
# Base URL: https://www.python.org
# Blocked: False
# Sitemaps found: 1
# URLs in sitemaps: 342
# Crawl-delay: None
# Sitemap directives in robots.txt: 1
# What pace does the site ask for?
if info.robots.crawl_delay:
print(f"Wait {info.robots.crawl_delay}s between requests")
# May I fetch this path?
info.robots.is_allowed("/api/users") # True / False
info.robots.is_allowed("/admin", user_agent="MyBot/1.0")
# Every deduplicated URL the site's own sitemaps declare
for url in info.urls:
print(url.loc, url.lastmod, url.changefreq, url.priority)
جزئیات بهازای هر عامل هنگام نیاز در دسترس است: info.robots.groups هر بلوک
User-agent را با allows، disallows و crawl_delay آن، به ترتیب سند نگه
میدارد. اگر سایتی اصلاً robots.txt نداشته باشد، is_allowed() برای همهچیز
True بازمیگرداند — نبودِ سیاست، خود همان سیاست است.
پاداش اسکرپینگِ نقشهمحور: بهجای کشف نشانیها با پیمایش (کُند، پرسروصدا، ناقص)، از فهرست خودِ نگهدارندگان آغاز میکنید. آنچه را که سایت مهم اعلام میکند، با سرعتی که قابلقبول اعلام میکند و با کسری از درخواستها اسکرپ میکنید.
کشف فعال: گراف پیوندها
برخی سایتها هیچ نقشهی سایتی منتشر نمیکنند. برای آنها، crawl() یک پیمایشِ
سطحبهسطحِ کراندار را از نشانی پایه اجرا میکند و یک LinkGraph از صفحههای
داخلی و پیوندهای خروجی بازمیگرداند:
from sitemapper import crawl
graph = crawl("https://example.com", max_pages=50, max_depth=2)
print(graph.summary())
# Pages crawled (internal): 50
# External URLs seen: 87
# Top external domains: ...
این به شما توپولوژی واقعی را میگوید — که کدام صفحه به چه چیزی پیوند دارد — تا بتوانید تصمیم بگیرید که آیا سایت اصلاً ارزش یک اسکرپرِ ساختیافته را دارد یا نه. کشف و پیمایش عمداً فراخوانیهای جداگانهاند: گام منفعل هرگز HTML را دریافت نمیکند، پس همیشه میتوانید پیش از تصمیم به پیمایش، مؤدبانه شناسایی کنید.
ساختهشده بر همان لایهی انتقالِ تابآور
شناسایی سایت بیفایده است اگر خودِ شناسایی پشت دیوارِ رباتها گیر بیفتد. همهی
ارتباط HTTP در sitemapper از میان
unblock_requests میگذرد —
لایهی انتقالِ جعلکنندهی TLS از
نوشتهی ما دربارهی لایهی انتقال ضدربات —
تا robots.txt و نقشههای سایت حتی در سایتهای پشت Cloudflare نیز بازگردند. یک
نمونهی FlareSolverr یا سازوکار پشتیبانِ Wayback Machine را میتوان با متغیرهای
محیطی (SITEMAPPER_FLARESOLVERR_URL، SITEMAPPER_WAYBACK_FALLBACK=1) یا از طریق
کلاس Sitemapper فعال کرد.
چرا این مهم است
تأخیر پیمایش: سایتی که Crawl-delay: 2 را اعلام میکند به شما میگوید با چه
سرعتی میخواهد مورد درخواست قرار گیرد. آن را نادیده بگیرید تا مسدود شوید — یا سایت
را برای همه دچار افت کیفیت کنید. به آن احترام بگذارید تا اسکرپر شما جوانمردانه
بازی کند.
نقشههای سایت بهجای پیمایش: یک نقشهی سایت آنچه را که سایت میخواهد نمایه شود فهرست میکند. پیمایشِ کورکورانهی پیوندها میتواند برای یافتن همان محتوا پنج برابر نشانی را لمس کند. آنجا که نقشهی سایت وجود دارد از آن آغاز کنید؛ هم برای شما سریعتر است و هم بار سبکتری بر سرور میگذارد.
دامنه پیش از کد: برخی سایتها در robots.txt اسکرپینگ را یکسره ممنوع میکنند؛
برخی نقشههای سایتی دارند که پیشاپیش هر آنچه نیاز دارید را در بر میگیرند. ده
ثانیه discover() پیش از آنکه روی یک تجزیهگر سرمایهگذاری کنید به شما میگوید در
کدام وضعیت هستید.
ابزار
pip install sitemapper
pip install sitemapper[stealth] # adds curl_cffi TLS impersonation
آن را بهعنوان کتابخانه به کار ببرید، یا از خط فرمان — --json FILE کل کشف را
در یک فایل برای مصرف ابزارهای دیگر مینویسد، --crawl گام گراف پیوندها را میافزاید:
python -m sitemapper https://example.com
python -m sitemapper https://example.com --crawl --max-pages 50 --json out.json
این نرمافزار آزاد است و بر سختافزار خودِ شما اجرا میشود. هر اسکرپر را با شناسایی آغاز کنید.