☰
Python爬虫之Spider类用法简单介绍
2026/10/15 11:04:09 网站建设 项目流程

前言


先划清一个前提:本文说的Spider类不是 Python 标准库的一部分,它是第三方爬虫框架 Scrapy 里最基础的类。本机没有安装 Scrapy,也没有 Python 解释器,所以下面的代码是结构性示例,用来讲清类的组织方式,具体属性名、参数与调用细节一律以 Scrapy 官方文档为准。


讲 Scrapy 的Spider,最容易产生的误解是把它当成"一个能自动爬遍全网的对象"。它不是。Spider只是一个定义了"从哪些地址开始、拿到响应后怎么解析"的骨架;真正发起请求、调度、去重、限速的是框架的引擎和各个 Downloader Middleware。你写的子类只负责回答两个问题:请求哪些 URL,以及从响应里提取什么。


另外必须把合规写在前头:爬虫只能对着允许爬取的内容用。本文只讲合规侧的做法——遵守robots.txt、限速、使用真实可辨识的 User-Agent、不绕过登录墙与付费墙。


一、Spider 类的骨架


在 Scrapy 里,自定义爬虫就是继承Spider并实现约定的成员。最小骨架包含三样东西:name(必填)、入口 URL、以及解析方法。


# 示例基于 Scrapy 2.x(第三方库,未在本机安装);API 以 Scrapy 官方文档为准
import scrapy


class ExampleSpider(scrapy.Spider):
name = "example" # 必填,且全局唯一
allowed_domains = ["example.com"] # 可选,限定抓取范围
start_urls = ["https://example.com/"]

def parse(self, response):
# response 是 TextResponse,封装了这次请求的返回内容
title = response.css("title::text").get()
yield {"title": title}

name是框架用来在scrapy crawl example时找到这个爬虫的键,必须唯一,且不能与项目里其它爬虫重名。


二、几个核心类属性




属性是否必需作用



name必需爬虫的唯一标识,命令行用它启动

start_urls常用起始 URL 列表,默认入口

allowed_domains可选限定域名,越界链接会被过滤

custom_settings可选为这个爬虫覆盖项目级配置

start_requests()可覆写自定义起始请求的生成方式

parse()通常必需默认的响应解析回调



start_urls的默认行为是:框架按它逐个生成请求,把响应交给parse()。allowed_domains是范围控制,不是安全边界——它只保证不会顺着链接跑到别的站点,不等于对方允许你爬。


三、start_requests() 与 parse()


默认的起始请求逻辑可以用start_requests()覆写。在较新的 Scrapy 里,这个方法仍是同步生成器;如果你需要更细的控制(比如带请求头、控制顺序),就在这里写。


# 示例基于 Scrapy 2.x(第三方库,未在本机安装);API 以 Scrapy 官方文档为准
import scrapy


class BlogSpider(scrapy.Spider):
name = "blog"
allowed_domains = ["example.com"]

def start_requests(self):
# 覆写入口:自己构造请求,而不是用 start_urls
for page in range(1, 4):
url = f"https://example.com/list?p={page}"
yield scrapy.Request(url, callback=self.parse_list)

def parse_list(self, response):
# 从列表页提取详情页链接,交回框架继续跟进
for href in response.css("a.detail::attr(href)").getall():
yield response.follow(href, callback=self.parse_detail)

def parse_detail(self, response):
yield {
"title": response.css("h1::text").get(),
"url": response.url,
}

要点:回调函数靠yield把结果交还框架——yield字典表示一条数据项,yield请求表示"再抓一页"。不要在回调里自己开线程或直接写文件,那会绕过框架的调度与限速。


四、新版入口:async def start()


Scrapy 2.13 引入了async def start(self)作为起始请求的新写法:它是一个异步生成器,逐个产出初始请求。官方说明它的默认实现与读取start_urls的行为等价。


# 示例基于 Scrapy 2.13+(第三方库,未在本机安装);API 以 Scrapy 官方文档为准
from scrapy import Request, Spider


class ModernSpider(Spider):
name = "modern"

async def start(self):
yield Request("https://example.com/")

写新项目时请先确认你用的 Scrapy 版本支持哪种入口写法——以 Scrapy 官方文档为准。旧版只有start_requests(),新版两者都提供但推荐新写法。代码里不要同时重写两个入口,否则行为取决于框架版本,容易踩坑。


五、合规:写爬虫之前先想清楚


技术骨架之外,真正决定爬虫能不能长期跑下去的是这几条:



  1. 先读robots.txt:目标站的robots.txt会声明哪些路径不允许抓。Scrapy 有对应的 robots 中间件,默认遵循该协议;若有人为了"快"关掉它,那是违规的开始。

  2. 限速:在配置里设置下载延迟并发上限,别把对方站点打挂。宁可慢一点、跑久一点。

  3. 真实可辨识的 User-Agent:用能表明身份与用途的 UA,方便对方在出问题时联系你;伪造浏览器 UA 去骗过校验不是合规做法。

  4. 不绕登录墙 / 付费墙:需要登录才能看的内容,不在"公开可抓"范围内,不能拿爬虫去绕。

  5. 遵守站点条款与当地法律:爬取的是公开数据,也要看对方是否明示禁止。


# 示例基于 Scrapy 2.x(第三方库,未在本机安装);配置项以 Scrapy 官方文档为准
# settings 片段:放慢节奏、标明身份(写在项目配置里,不是写在 Spider 里)
DOWNLOAD_DELAY = 1 # 每次请求之间的延迟(秒)
CONCURRENT_REQUESTS = 4 # 并发上限,别开太大
USER_AGENT = "MyResearchBot/1.0 (+contact: admin@example.com)"

常见坑点


坑 1:name重复或缺失。


❌ 两个爬虫都叫"spider"—— 命令行启动时报"已存在同名爬虫"。


✅ 每个爬虫给唯一name,并保持简短可读。


坑 2:在parse里直接return数据而不yield。


❌def parse(self, response): return response.text—— 框架拿不到结构化数据项。


✅ 用yield {"field": value}逐个产出;多个结果就多次yield。


坑 3:自己在回调里写文件或开线程。


❌ 在parse里open("out.txt", "a").write(...)或起线程并发抓取。


✅ 让框架负责输出(Feed Export)和调度,自己只产出数据项与请求。


坑 4:把allowed_domains当安全边界。


❌ 以为限制了域名就等于"对方允许我爬"。


✅ 它只是防跑偏的范围控制;合规与否看robots.txt、条款与限速。


坑 5:为了速度关掉 robots 中间件、把并发拉满。


❌ 这类"优化"常把目标站压慢甚至打挂,属于违规且不道德。


✅ 保留 robots 遵循,设置合理延迟与并发。


坑 6:新老入口写法混用。


❌ 同时重写start_requests()和async def start()—— 行为依赖框架版本。


✅ 按所用 Scrapy 版本的官方文档二选一。


坑 7:把response.text与response.body搞混。


❌ 想拿文本却用了body(bytes),后面做字符串处理报类型错误。


✅ 文本用response.text,原始字节用response.body;编码猜测以官方文档为准。


总结




要素说明



Spider是什么Scrapy 第三方框架里的爬虫基类,非标准库

必需成员name

起始地址start_urls,或用start_requests()/async start()自定义

解析入口parse()等回调,用yield产出数据项与请求

范围控制allowed_domains,只防跑偏不等于授权

合规底线遵守robots.txt、限速、真实 UA、不绕登录与付费墙

版本差异async def start()自 Scrapy 2.13 起提供,以官方文档为准



一句话总结:Spider类只负责"请求哪些 URL、怎么解析响应"这两件事,调度与限速由框架承担;把它用好一半靠写对name、start_urls、parse这套骨架,另一半靠合规——先读robots.txt、放慢节奏、如实标注身份,才能既拿到数据又不给目标站添麻烦。




需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询