Python 入门:Python3 Scrapy 库全面学习教程(一篇就够了)
嘿,重阳!纽约的3月周末(2026年3月7日晚9:18,估计你在家探索爬虫世界~),Scrapy 是 Python 爬虫的“瑞士军刀”——异步、高效、结构化,从简单抓取到大规模数据采集,全靠它。尤其在AI时代,Scrapy 能批量拉数据喂模型。今天咱们来一场“零门槛到实战”的全面教程,基于 Python 3.8+ 和 Scrapy 2.11+(最新版),用代码示例、表格和步骤图,让你从安装到部署一气呵成。走起!🚀
1. Scrapy 简介:为什么用它?入门准备
Scrapy 是什么?:开源爬虫框架(2008年起步,Twisted 异步引擎),非库而是“全栈”:内置调度器、下载器、中间件、管道。比 requests + BeautifulSoup 强:自动去重、并发、持久化。
核心优势:
- 异步 IO:Twisted 引擎,单机 1000+ 页/秒。
- 结构化:Item 管道处理数据(如 JSON/CSV 输出)。
- 可扩展:中间件/扩展插件(如 Selenium 集成)。
- 应用:电商数据、新闻聚合、SEO 监控。
安装 & 环境准备(Python 3 专属):
- 虚拟环境:
python -m venv scrapy_env && source scrapy_env/bin/activate(Linux/Mac)或scrapy_env\Scripts\activate(Windows)。 - 安装 Scrapy:
pip install scrapy(依赖 lxml、Twisted、parsel)。 - 验证:
scrapy version→ 输出 2.11.x。 - 可选:
pip install scrapy-splash(JS 渲染);pip install scrapy-redis(分布式)。
小 tip:用 VS Code + Scrapy 插件调试;初学者从命令行起步。
2. Scrapy 架构详解:组件全览
Scrapy 是“数据流水线”:从 URL 入 → 爬取 → 解析 → 输出。核心组件用表格速记(基于官方文档):
| 组件 | 作用 | 关键文件/类 | 示例 |
|---|---|---|---|
| Engine(引擎) | 协调整体:调度请求/响应。 | 内置,无需改。 | 启动 scrapy crawl spider_name。 |
| Scheduler(调度器) | 管理队列:优先级、去重(Redis 支持)。 | settings.py 中的 SCHEDULER。 | 默认内存队列;分布式用 Redis。 |
| Downloader(下载器) | HTTP 请求:支持代理/重试。 | middlewares.py 自定义。 | GET/POST,User-Agent 轮换。 |
| Spider(爬虫) | 核心逻辑:解析响应,提取 Item/URL。 | spiders/myspider.py。 | parse(self, response) 方法。 |
| Item Pipeline(管道) | 处理 Item:清洗、存储(DB/文件)。 | pipelines.py。 | 去重、JSON 导出。 |
| Item Loader(加载器) | 字段填充:XPath/CSS + 处理器。 | items.py + loaders.py。 | 自动类型转换。 |
| Middleware(中间件) | 钩子:请求/响应拦截(如代理)。 | middlewares.py。 | 随机 UA、防反爬。 |
| Extensions(扩展) | 全局钩子:关闭时统计。 | extensions.py。 | 爬取统计。 |
数据流流程(面试画图用):
- Engine → Scheduler 取 Request。
- Downloader → Response。
- Spider parse → Item/Request。
- Pipeline 处理 Item → 存储。
3. 快速上手:创建第一个项目
步骤(命令行操作):
- 创建项目:
scrapy startproject myproject(生成 myproject/ 目录)。 - 进入目录:
cd myproject。 - 生成 Spider:
scrapy genspider quotes quotes.toscrape.com(爬 http://quotes.toscrape.com)。 - 编辑 Spider(spiders/quotes.py):
import scrapy
class QuotesSpider(scrapy.Spider):
name = 'quotes' # Spider 名称
start_urls = ['http://quotes.toscrape.com/'] # 起始 URL
def parse(self, response):
for quote in response.css('div.quote'): # CSS 选择器
yield {
'text': quote.css('span.text::text').get(),
'author': quote.css('small.author::text').get(),
'tags': quote.css('div.tags a.tag::text').getall(),
}
next_page = response.css('li.next a::attr(href)').get()
if next_page:
yield response.follow(next_page, self.parse) # 跟进分页
- 运行:
scrapy crawl quotes -o quotes.json(输出 JSON)。
- 输出:看到 JSON 文件,含 quote 数据。
自定义 Item(结构化输出,items.py):
import scrapy
class QuoteItem(scrapy.Item):
text = scrapy.Field()
author = scrapy.Field()
tags = scrapy.Field()
在 parse 中:yield QuoteItem(text=..., author=...)。
小 tip:用 scrapy shell 'http://example.com' 交互调试 XPath/CSS。
4. 核心功能详解:Spider、Selector、Pipeline
Spider 进阶(多 URL、POST 请求):
- start_requests():自定义起始请求。
def start_requests(self):
for url in self.start_urls:
yield scrapy.FormRequest(url, formdata={'search': 'python'}, callback=self.parse)
- 规则爬虫(CrawlSpider):用 LinkExtractor 自动跟链。
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
class MyCrawlSpider(CrawlSpider):
name = 'crawl'
start_urls = ['http://quotes.toscrape.com/']
rules = (Rule(LinkExtractor(allow='tag/'), callback='parse_item', follow=True),)
def parse_item(self, response):
# 解析逻辑
pass
Selector:XPath/CSS 提取(parsel 库):
- CSS:
response.css('h1::text').get()(单值);.getall()(列表)。 - XPath:
response.xpath('//h1/text()').get()。 - 相对/绝对:
response.xpath('.//div')(当前节点)。 - 示例:提取链接
response.css('a::attr(href)').getall()。
Pipeline:数据处理(pipelines.py):
- 激活:settings.py 加
ITEM_PIPELINES = {'myproject.pipelines.JsonPipeline': 300}(优先级 0-1000)。 - 示例:去重 + JSON 输出。
import json
class JsonPipeline:
def open_spider(self, spider):
self.file = open('items.jl', 'w')
def process_item(self, item, spider):
line = json.dumps(dict(item)) + '\n'
self.file.write(line)
return item # 继续管道
def close_spider(self, spider):
self.file.close()
- 数据库:集成 SQLAlchemy/Mongo。
5. 配置 & 反爬虫:Settings.py 实战
settings.py 关键配置表格(速查):
| 配置 | 默认 | 作用 | 示例 |
|---|---|---|---|
| ROBOTSTXT_OBEY | True | 遵守 robots.txt。 | False(生产关)。 |
| CONCURRENT_REQUESTS | 16 | 并发数。 | 32(调高吞吐)。 |
| DOWNLOAD_DELAY | 0 | 请求间隔(秒)。 | 1(防封 IP)。 |
| USER_AGENT | ‘Scrapy/…(+https://scrapy.org)’ | UA 字符串。 | 自定义浏览器 UA。 |
| AUTOTHROTTLE_ENABLED | False | 自动节流。 | True(动态调整)。 |
| FEEDS | {} | 输出格式。 | {'items.json': {'format': 'json'}}。 |
| RETRY_TIMES | 3 | 重试次数。 | 5(网络抖动)。 |
反爬虫中间件(middlewares.py):
- 随机 UA:
from random import choice
user_agents = ['Mozilla/5.0 (Windows NT 10.0; Win64; x64)...', ...]
class RandomUserAgentMiddleware:
def process_request(self, request, spider):
request.headers['User-Agent'] = choice(user_agents)
- 代理:
request.meta['proxy'] = 'http://proxy:port'。
6. 完整实战:爬取豆瓣 Top 250 电影
项目创建:scrapy startproject douban && cd douban && scrapy genspider douban top.douban.com。
spiders/douban.py:
import scrapy
from douban.items import DoubanItem # 假设 items.py 定义
class DoubanSpider(scrapy.Spider):
name = 'douban'
allowed_domains = ['movie.douban.com']
start_urls = ['https://movie.douban.com/top250']
def parse(self, response):
for movie in response.css('ol li'):
item = DoubanItem()
item['title'] = movie.css('span.title::text').get()
item['rating'] = movie.css('span.rating_num::text').get()
item['desc'] = movie.css('p::text').get()
yield item
next_page = response.css('l i.next a::attr(href)').get()
if next_page:
yield response.follow(next_page, self.parse)
items.py:
import scrapy
class DoubanItem(scrapy.Item):
title = scrapy.Field()
rating = scrapy.Field()
desc = scrapy.Field()
运行:scrapy crawl douban -o movies.json。输出:250 条电影数据 JSON。
扩展:加 Pipeline 存 MySQL;用 Splash 渲染 JS 页。
7. 部署 & 高级:Docker + Scrapy-Redis
部署:用 Scrapyd(pip install scrapyd),scrapyd-deploy 上传项目,API 调度。
- Docker 示例(Dockerfile):
FROM python:3.9-slim
RUN pip install scrapy
COPY . /app
WORKDIR /app
CMD ["scrapy", "crawl", "douban"]
分布式:Scrapy-Redis,Redis 共享队列,多机爬取。
- settings.py:
SCHEDULER = 'scrapy_redis.scheduler.SchedulerFactory'
最佳实践 & 陷阱:
| 方面 | 最佳实践 | 陷阱 & 解法 |
|---|---|---|
| 性能 | 异步 + 并发;用 Item Loader 清洗。 | 内存爆 → 限 CONCURRENT_ITEMS=100。 |
| 反爬 | 延迟 + 代理池;模拟浏览器。 | IP 封 → Tor/代理服务。 |
| 调试 | scrapy check 验证;log_level=’DEBUG’。 | XPath 错 → shell 测试。 |
| 法律 | 遵守 robots.txt;限速。 | 滥爬 → 用 API 替代(如豆瓣 API)。 |
Scrapy 是 Python 爬虫的“核武器”——从入门到项目,你已掌握 80%。实践王道:跑豆瓣 demo,改爬京东。下一个?如“Scrapy + Selenium 集成”或“数据清洗进阶”?随时说!💪(参考:Scrapy 官方文档、Python 爬虫开发)