crawlspider 不是整站爬虫,因其仅从html中提取链接,无法处理robots.txt、js渲染、api动态url或sitemap.xml等。需人工补全url来源并谨慎配置rule与linkextractor参数。

CrawlSpider 不能真正“抓取整站”,它只按规则爬指定路径,盲目设宽泛规则大概率导致无限爬、重复爬或被封。
为什么 CrawlSpider 不是“整站爬虫”
CrawlSpider 的 CrawlSpider 类本质是规则驱动的链接提取器,不是站点地图解析器或域名遍历器。它依赖 Rule 中定义的 LinkExtractor,而后者只从当前响应 HTML 中提取 <a></a> 链接——这意味着:它看不到 robots.txt 禁止的路径、JS 渲染的路由、API 返回的动态 URL、sitemap.xml 中的页面,更不会主动拼接 /page/2、/category/123 这类逻辑分页。
常见错误现象:start_urls 只写首页,allow 设成 r'.*',结果爬虫在首页反复提取自身链接,陷入死循环;或匹配到大量外链(如社交媒体按钮),把爬虫带出目标域名。
使用场景仅限于:结构清晰、导航链完整、URL 规则可预测的静态站点(如博客归档页、文档目录页)。
Rule 和 LinkExtractor 的关键参数怎么配
真正控制“爬多深、爬哪些”的是 Rule 的 link_extractor 和回调逻辑,不是 CrawlSpider 本身。
-
allow必须用具体正则,例如r'/blog/\d+/'或r'/products/.+\.html',避免r'.*'或空列表 -
deny要显式排除登录页、搜索页、分页参数(如r'\?page=\d+'),否则会重复抓/list?page=1、/list?page=2 -
restrict_xpaths比restrict_css更可靠,推荐用//nav//a | //article//a明确限定导航区域,避免提取页脚、广告位的链接 - 多个
Rule要注意顺序:靠前的 rule 若匹配并设置了follow=True,后续 rule 就不会再处理该响应;需把“提取详情页”的 rule 放在“提取列表页”的 rule 之后
如何避免漏页和误爬
真正的“覆盖整站”需要人工补全三类 URL 来源,CrawlSpider 本身不提供自动发现能力:
- 从
robots.txt解析Sitemap:行,用scrapy.Request单独抓取 sitemap.xml,再用xml.etree.ElementTree提取所有<loc></loc>,丢进start_requests - 对已知分类页(如
/category/)手动构造 URL 列表,例如用itertools.product(['shoes','clothes'], ['new','sale'])生成/category/shoes/new - 在 parse_start_url 或 callback 中检查响应是否有
rel="next"分页链接,或 JSON 响应里的"next_page"字段,主动发起新请求
性能影响:过度依赖 follow=True 会让 Scrapy 在每个响应里都跑一遍 LinkExtractor,比直接 yield Request 慢 20%–40%;对于大站,建议把链接发现逻辑收口到少数几个 callback 中,而非全靠 Rule。
域名和反爬绕过必须手动加
CrawlSpider 不自动处理域名跳转、协议切换或 referer。如果目标站有 https://www.example.com 和 https://blog.example.com 两个子域,且规则里没限制 deny_domains,爬虫可能跨域乱爬。
容易踩的坑:
- 没设
allowed_domains = ['example.com'],结果爬到百度统计 JS 链接又跳回自己站,形成环路 - 没在
settings.py开ROBOTSTXT_OBEY = True,但实际站点 robots.txt 禁了/admin/,结果仍去尝试访问,触发风控 - 没配
DOWNLOAD_DELAY或AUTOTHROTTLE_ENABLED,单机并发 16,5 分钟内发 5000 请求,IP 直接被 403
真实项目中,90% 的“整站抓取失败”问题出在链接发现逻辑缺失或反爬策略没对齐,而不是 CrawlSpider 用得不对。别迷信 Rule,该手写 Request 的地方就写。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











