什么是 Scrapy?
Scrapy 是一个基于 Python 的高级网络爬虫框架,专门用于从网页中抓取数据(也称为“网络抓取”或“网页采集”)。它最初由 Scrapinghub 公司开发并开源,现已成为 Python 社区中最广泛使用的爬虫框架之一。
Scrapy 不仅支持同步和异步请求,还内置了对数据提取、数据清洗、数据存储等流程的支持,极大提升了开发效率。
主要特点
- 高性能:基于 Twisted 异步网络库,支持高并发请求。
- 可扩展性强:模块化设计,易于自定义中间件、管道和扩展。
- 内置数据提取机制:支持使用 XPath 和 CSS 选择器提取数据。
- 自动处理常见任务:如 robots.txt、HTTP 重试、用户代理设置、Cookie 管理等。
- 丰富的输出格式:支持将数据导出为 JSON、CSV、XML 等格式。
- 与数据库集成方便:可通过 Pipeline 轻松对接 MongoDB、MySQL、PostgreSQL 等数据库。
- 调试和监控工具完善:提供命令行工具、日志系统和调试支持。
Scrapy 的核心组件
Scrapy 的架构采用经典的“生产者-消费者”模型,其主要由以下几个核心组件构成:
1.Spider(爬虫)
Spider 是用户编写的类,定义了如何抓取某个网站(或一组网站),包括起始 URL、如何跟踪链接、如何解析页面内容等。每个 Spider 继承自scrapy.Spider类,并实现核心方法如start_requests()和parse()。
import scrapy class ExampleSpider(scrapy.Spider): name = 'example' start_urls = ['http://example.com'] def parse(self, response): yield { 'title': response.css('h1::text').get(), 'url': response.url }2.Engine(引擎)
Scrapy 引擎负责控制整个系统的数据流,协调各个组件之间的交互。它是 Scrapy 的核心调度器。
3.Scheduler(调度器)
接收引擎发送的请求,并按顺序进行排队,等待下载器处理。支持优先级队列和去重机制(通过dupefilter实现)。
4.Downloader(下载器)
负责向目标网站发送 HTTP/HTTPS 请求,并返回响应(Response)给引擎。Scrapy 使用异步方式处理多个请求,提升效率。
5.Downloader Middleware(下载中间件)
位于引擎和下载器之间,允许你在请求发送前和响应接收后插入自定义逻辑,例如添加代理、修改请求头、处理异常等。
6.Spider Middleware(爬虫中间件)
位于引擎和爬虫之间,用于处理爬虫输入(Response)和输出(Items 或 Requests),可用于清洗数据、重试失败请求等。
7.Item Pipeline(项目管道)
负责处理爬虫提取的数据(Item),常见的操作包括数据验证、去重、清洗、存储到数据库或文件等。
class SaveToDatabasePipeline: def process_item(self, item, spider): # 将 item 存入数据库 return item # 必须返回 item 或抛出 DropItem 异常8.Item(项目)
用于定义爬取数据的结构,类似于 Python 的字典,但具有更强的字段约束和元数据支持。
import scrapy class ProductItem(scrapy.Item): name = scrapy.Field() price = scrapy.Field() url = scrapy.Field()安装 Scrapy
Scrapy 支持 Python 3.7 及以上版本。你可以使用 pip 安装:
pip install scrapy安装完成后,可以通过以下命令创建一个新项目:
scrapy startproject myproject cd myproject项目结构如下:
myproject/ ├── scrapy.cfg └── myproject/ ├── __init__.py ├── items.py ├── middlewares.py ├── pipelines.py ├── settings.py └── spiders/ └── __init__.py编写第一个爬虫
在spiders/目录下创建一个爬虫文件,例如quotes_spider.py:
import scrapy class QuotesSpider(scrapy.Spider): name = 'quotes' start_urls = ['http://quotes.toscrape.com/'] def parse(self, response): 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, self.parse)运行爬虫:
scrapy crawl quotes -o quotes.json该命令会启动名为quotes的爬虫,并将结果保存为quotes.json文件。
高级功能与技巧
1.使用 Item 和 Pipeline
定义items.py中的结构:
import scrapy class QuoteItem(scrapy.Item): text = scrapy.Field() author = scrapy.Field() tags = scrapy.Field()在pipelines.py中添加存储逻辑(如保存到 MongoDB)。
2.设置请求头和代理
在settings.py中配置:
DEFAULT_REQUEST_HEADERS = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36' } # 启用随机 User-Agent(需安装 scrapy-useragents) DOWNLOADER_MIDDLEWARES = { 'scrapy.downloadermiddlewares.useragent.UserAgentMiddleware': None, 'scrapy_useragents.downloadermiddlewares.useragents.UserAgentsMiddleware': 500, }3.处理 JavaScript 渲染页面
Scrapy 本身不支持 JavaScript 渲染。对于动态网页,可结合Selenium或Playwright使用:
from scrapy_splash import SplashRequest def start_requests(self): yield SplashRequest(url='http://example.com', callback=self.parse)提示:可使用
scrapy-splash或scrapy-playwright插件。
注意事项与最佳实践
遵守 robots.txt
在settings.py中启用:ROBOTSTXT_OBEY = True控制爬取速度
避免对目标服务器造成压力:DOWNLOAD_DELAY = 1 # 每次请求间隔1秒 CONCURRENT_REQUESTS_PER_DOMAIN = 4避免被封禁
使用代理池、随机 User-Agent、CAPTCHA 处理机制。合法合规
确保爬取行为符合目标网站的使用条款及当地法律法规。
总结
Scrapy 是一个功能强大、结构清晰、性能优越的 Python 网络爬虫框架,适用于从小型数据采集到大规模分布式爬虫系统的各种场景。其模块化设计和丰富的生态系统使得开发者能够快速构建稳定、高效的爬虫程序。
无论是用于数据分析、市场调研、价格监控还是学术研究,Scrapy 都是一个值得掌握的工具。
扩展资源
- 官方文档:https://docs.scrapy.org
- GitHub 仓库:https://github.com/scrapy/scrapy
- 社区论坛:https://stackoverflow.com/questions/tagged/scrapy