Python爬虫进阶:Scrapy框架入门与实战
文章目录
- Python爬虫进阶:Scrapy框架入门与实战
-
- 前言
- 一、安装与创建项目
- 二、编写第一个Spider
- 三、定义Item数据模型
- [四、Item Pipeline:数据后处理](#四、Item Pipeline:数据后处理)
- 五、中间件配置
- 六、常用配置项
- 总结
- [✅ 亮点总结](#✅ 亮点总结)
- 适用场景
- 扩展方向
前言
当你需要爬取数据量较大、需求复杂的网站时,自己徒手编写的爬虫脚本在效率、可维护性、扩展性上都显得力不从心。Scrapy是Python最强大的爬虫框架,它提供了完整的爬虫生态系统:异步引擎、自动去重、数据管道、中间件支持。
requests + BeautifulSoup 和 Scrapy 的本质区别是什么? 前者是"手动挡"------你需要自己管理请求队列、处理并发、实现去重和错误重试;后者是"自动挡"------框架已经为你封装好了异步引擎、请求调度、管道处理等,你只需要关注数据提取的逻辑。对于一次性爬取几十个页面的小任务,requests足够;但对于需要持续爬取数千个页面的项目,Scrapy的生产力优势是碾压级的。本文将从项目创建开始,带你一步步掌握Scrapy的核心组件。
一、安装与创建项目
bash
pip install scrapy
scrapy startproject myproject
cd myproject
生成的项目结构每个文件都有明确的职责。理解这个结构是使用Scrapy的第一步------初学者最容易犯的错误就是在错误的位置创建爬虫文件或者忘记注册Pipeline。
myproject/
├── scrapy.cfg # 部署配置
└── myproject/
├── items.py # 定义数据模型
├── middlewares.py # 中间件
├── pipelines.py # 数据管道
├── settings.py # 全局设置
└── spiders/ # 爬虫目录
项目结构解读 :settings.py 是Scrapy的"总控制台"------在这里可以配置并发数、下载延迟、中间件权重等全局参数;pipelines.py 是数据处理的"流水线"------数据在这里被清洗、验证和存储;middlewares.py 是请求的"代理层"------在这里添加UA伪装、IP代理等。
二、编写第一个Spider
Spider是Scrapy的核心组件,负责定义"爬取什么"和"如何提取数据"。每个Spider需要指定一个唯一的 name(用于命令行启动)和起始URL(start_urls),并实现 parse() 方法来处理响应。parse() 方法的返回值可以是字典、Item对象或一个新的Request------返回Request时Scrapy会自动将其加入调度队列,这为实现翻页爬取提供了极大的便利。
在spiders/目录下创建quotes_spider.py:
python
import scrapy
class QuotesSpider(scrapy.Spider):
name = "quotes" # 爬虫唯一标识
start_urls = ["http://quotes.toscrape.com/"]
def parse(self, response):
# 使用CSS选择器提取数据
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("a.tag::text").getall(),
}
# 翻页
next_page = response.css("li.next a::attr(href)").get()
if next_page:
yield response.follow(next_page, callback=self.parse)
运行爬虫:
bash
scrapy crawl quotes -o quotes.json # 输出为JSON文件
三、定义Item数据模型
Item是Scrapy的数据容器,类似于字典但提供了结构化的字段定义。为什么要用Item而不是直接返回字典?主要原因有三:一是类型安全(使用ItemLoader时可以定义字段的处理规则),二是IDE支持(字段名有代码提示),三是可扩展性(Pipeline可以根据Item类型进行不同的处理)。对于中小型项目,用字典也是可以的;但当项目规模增大、团队协作增多时,Item的优势就会显现。
python
import scrapy
class QuoteItem(scrapy.Item):
text = scrapy.Field()
author = scrapy.Field()
tags = scrapy.Field()
在Spider中使用Item:
python
from myproject.items import QuoteItem
def parse(self, response):
for quote in response.css("div.quote"):
item = QuoteItem()
item["text"] = quote.css("span.text::text").get()
item["author"] = quote.css("small.author::text").get()
item["tags"] = quote.css("a.tag::text").getall()
yield item
四、Item Pipeline:数据后处理
Pipeline 是Scrapy数据处理的核心环节,用于清洗、验证、存储数据。每个Pipeline类需要实现 process_item() 方法,它接收一个Item并返回(修改后的)Item或DropItem异常。Pipeline的执行顺序 :多个Pipeline按 ITEM_PIPELINES 中配置的数字从小到大的顺序执行,数字越小优先级越高。这个设计让你可以将"清洗→去重→存MySQL→存Elasticsearch"这样的流程拆分成多个独立的Pipeline组件。
python
class MyprojectPipeline:
def process_item(self, item, spider):
# 清洗数据:去除文本首尾空白
item["text"] = item["text"].strip().replace("\u201c", "").replace("\u201d", "")
item["author"] = item["author"].strip()
return item
class JsonWriterPipeline:
def open_spider(self, spider):
self.file = open("output.json", "w", encoding="utf-8")
def process_item(self, item, spider):
import json
line = json.dumps(dict(item), ensure_ascii=False) + "\n"
self.file.write(line)
return item
def close_spider(self, spider):
self.file.close()
在settings.py中启用Pipeline(数字越小优先级越高):
python
ITEM_PIPELINES = {
"myproject.pipelines.MyprojectPipeline": 300,
"myproject.pipelines.JsonWriterPipeline": 800,
}
五、中间件配置
下载中间件 是Scrapy最灵活的部分之一------它在每个请求发出前和每个响应到达后提供"钩子",让你可以在请求/响应生命周期中插入自定义逻辑。常见的中间件用途包括:User-Agent轮换(绕过简单的UA检测)、代理IP管理(绕过IP封禁)、请求重试(处理临时性错误)、Cookie管理(维持登录状态)。中间件的编写遵循标准接口,process_request 处理请求,process_response 处理响应。
python
# middlewares.py
import random
class RotateUserAgentMiddleware:
user_agents = [
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) ...",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) ...",
]
def process_request(self, request, spider):
request.headers["User-Agent"] = random.choice(self.user_agents)
在settings.py中激活:
python
DOWNLOADER_MIDDLEWARES = {
"myproject.middlewares.RotateUserAgentMiddleware": 543,
}
六、常用配置项
Scrapy的强大之处在于其高度可配置性------通过 settings.py 中的配置,你可以精准控制爬虫的行为。每个配置项都有默认值,你可以按需调整。几个关键配置的注意事项 :ROBOTSTXT_OBEY 默认为True,意味着遵守目标网站的爬虫协议------在学习和测试时你可以设为False,但在商业项目中请务必尊重robots.txt;DOWNLOAD_DELAY 是控制请求频率的最简单方式,设置1-3秒的延迟可以有效降低被目标网站封禁的风险;CONCURRENT_REQUESTS 控制同时发出的请求数,不要设得太高以免被封IP。
python
# settings.py
ROBOTSTXT_OBEY = False # 是否遵守robots.txt
CONCURRENT_REQUESTS = 16 # 并发请求数
DOWNLOAD_DELAY = 1 # 下载延迟(秒)
RETRY_TIMES = 3 # 重试次数
DEFAULT_REQUEST_HEADERS = {
"Accept": "text/html,application/xhtml+xml",
"Accept-Language": "zh-CN,zh;q=0.9",
}
总结
Scrapy将爬虫开发抽象为Spider(数据采集) 、Item(数据模型) 、Pipeline(数据处理) 三大核心组件,配合中间件和配置实现高度可定制的爬虫流程。对于中大型爬虫项目,Scrapy是毋庸置疑的首选框架。
学习路线建议:Scrapy的学习曲线比requests+BeautifulSoup要陡,但它带来的工程化能力是质的飞跃。建议初学者按照"安装→创建项目→编写简单Spider→理解Item和Pipeline→学习中间件→掌握配置调优"的顺序循序渐进。不要一开始就试图掌握所有组件------先用最简单的Spider跑通数据采集,再逐步加入Item规范、Pipeline存储、中间件伪装等功能。另外,Scrapy官方文档质量很高,遇到问题时优先查阅官方文档和社区讨论。
✅ 亮点总结
- Scrapy 项目的标准目录结构拆解,从零建立工程化爬虫项目的完整流程
- Spider(采集)、Item(数据模型)、Pipeline(处理)三大组件分工明确,解耦清晰
- 中间件(Middleware)机制详解,掌握请求头伪装、IP 代理、重试策略等核心反反爬手段
- 实战案例:完整的 Scrapy 爬虫项目,包含命令行执行和数据导出(JSON/CSV)
适用场景
- 电商数据采集:爬取商品列表、价格变化、库存状态的批量监控
- 舆情分析:从新闻网站和社交媒体采集内容,进行文本分析和情感判断
- 竞品数据对比:定期抓取竞争对手网站数据,生成市场分析报告
扩展方向
- 学习 Scrapy-Redis 实现分布式爬虫,支持多台机器协同爬取
- 掌握 Splash/Selenium 与 Scrapy 的集成,解决 JavaScript 动态渲染页面
- 探索 Scrapy 的信号系统和扩展机制,实现自定义的数据收集和监控插件