Scrapy 是一个基于 Python 的开放源代码爬虫框架,设计用于快速抓取网站数据,并对其进行清洗、存储等操作。Scrapy 的核心特性是能够异步处理大量并发请求,从而实现高效的数据抓取。它支持多种数据格式的存储(如 JSON、CSV、XML、数据库等),并且有很多内建的功能来简化开发过程,如自动化抓取、响应处理、错误处理、代理支持等。
1. 安装 Scrapy
要安装 Scrapy,可以使用 pip 来安装:
pip install scrapy
2. Scrapy 项目结构
在 Scrapy 中,一个项目通常由多个组件组成,每个组件负责不同的任务。以下是 Scrapy 项目的基本结构:
myproject/
scrapy.cfg # 配置文件
myproject/
__init__.py
items.py # 数据模型,定义抓取的数据结构
middlewares.py # 中间件,用于处理请求和响应
pipelines.py # 数据管道,处理抓取到的数据
settings.py # 配置文件,包含项目的全局设置
spiders/
__init__.py
my_spider.py # 爬虫脚本,定义如何抓取数据
- scrapy.cfg:Scrapy 配置文件,包含项目的基本信息。
- items.py:定义抓取的数据结构(Item),它类似于 Django 中的模型,帮助你管理抓取到的数据。
- middlewares.py:定义请求和响应处理的中间件。你可以在中间件中加入额外的逻辑,比如请求修改、重定向处理、错误处理等。
- pipelines.py:数据管道。数据抓取之后可以通过管道进行存储或进一步处理。常见的操作包括数据清洗、去重、存储到数据库等。
- settings.py:项目的配置文件,包含了许多 Scrapy 的设置选项,比如并发请求数、下载延迟、用户代理等。
- spiders/:存放爬虫脚本的目录,每个爬虫负责抓取特定的网站数据。
3. Scrapy 工作流程
Scrapy 的工作流程可以分为以下几个步骤:
- 请求发起:Scrapy 爬虫从
start_urls中提取 URL,并开始发起请求。你也可以在爬虫中自定义start_requests()方法来发起请求。 - 请求处理:请求发送到目标网页,并且 Scrapy 会返回响应。你可以通过
parse方法处理这个响应。Scrapy 会将响应对象传递给爬虫中的解析函数(回调函数)。 - 数据提取:通过 CSS 选择器或 XPath 提取网页中的数据,并将这些数据封装成
Item对象。 - 数据存储:通过管道(Pipeline)将提取的数据存储到文件、数据库或其他存储介质中。
4. 基本用法
4.1 定义 Item(数据模型)
在 items.py 文件中定义要抓取的数据结构。每个 Item 是一个 Python 类,继承自 scrapy.Item,并且每个字段使用 scrapy.Field() 来定义。
# myproject/items.py
import scrapy
class MyprojectItem(scrapy.Item):
title = scrapy.Field()
link = scrapy.Field()
description = scrapy.Field()
date = scrapy.Field()
4.2 编写爬虫(Spider)
爬虫是 Scrapy 中用于抓取目标数据的核心组件。爬虫定义了如何请求网页、如何提取数据以及如何处理分页等。
# myproject/spiders/my_spider.py
import scrapy
from myproject.items import MyprojectItem
class MySpider(scrapy.Spider):
name = 'myspider'
start_urls = ['https://example.com']
def parse(self, response):
item = MyprojectItem()
item['title'] = response.css('h1::text').get()
item['link'] = response.url
item['description'] = response.css('div.description::text').get()
item['date'] = response.css('time::text').get()
yield item
name:爬虫的名称,在命令行中运行爬虫时使用。start_urls:爬虫启动时抓取的初始 URL。parse:解析响应并提取数据。parse方法通常是回调函数,用来处理请求返回的页面。
4.3 处理分页
很多网站的数据是分页的,你需要在爬虫中处理分页,通过 parse 方法提取下一页的 URL,并发起新的请求。
def parse(self, response):
# 提取数据
item = MyprojectItem()
item['title'] = response.css('h1::text').get()
yield item
# 处理分页
next_page = response.css('a.next::attr(href)').get()
if next_page:
yield scrapy.Request(url=next_page, callback=self.parse)
4.4 配置和设置
Scrapy 允许你在 settings.py 文件中配置项目的设置。例如,你可以设置并发请求数、下载延迟、用户代理等。
# myproject/settings.py
BOT_NAME = 'myproject'
SPIDER_MODULES = ['myproject.spiders']
NEWSPIDER_MODULE = 'myproject.spiders'
# 设置下载延迟(秒)
DOWNLOAD_DELAY = 2
# 设置并发请求数
CONCURRENT_REQUESTS = 16
# 启用数据管道
ITEM_PIPELINES = {
'myproject.pipelines.MyprojectPipeline': 1,
}
5. 高级特性
5.1 请求和响应处理
Scrapy 使用 Request 对象来表示 HTTP 请求,通过回调函数处理响应数据。Scrapy 支持异步处理请求,可以在回调函数中提取需要的内容,提交更多请求。
def start_requests(self):
urls = ['https://example.com/page1', 'https://example.com/page2']
for url in urls:
yield scrapy.Request(url, callback=self.parse)
def parse(self, response):
# 处理响应数据
next_page = response.css('a.next::attr(href)').get()
if next_page:
yield scrapy.Request(url=next_page, callback=self.parse)
5.2 中间件
Scrapy 提供了中间件的功能,可以用于修改请求和响应。常见的用途包括处理请求重试、使用代理、处理用户代理等。
class MyMiddleware:
def process_request(self, request, spider):
# 在请求发出之前修改请求
request.headers['User-Agent'] = 'Mozilla/5.0'
def process_response(self, request, response, spider):
# 在响应返回时修改响应
return response
5.3 管道
数据管道用于处理抓取到的数据。你可以在管道中清洗数据、去重、存储数据等操作。
class MyprojectPipeline:
def process_item(self, item, spider):
# 处理抓取到的数据
return item
如果需要将数据保存到文件或数据库,可以在管道中实现存储逻辑。
5.4 并发与延时
Scrapy 使用异步网络请求,因此可以支持高并发抓取。你可以通过配置设置并发请求数、下载延迟等参数。
CONCURRENT_REQUESTS = 32
DOWNLOAD_DELAY = 2 # 每个请求之间的延迟时间
5.5 使用代理
Scrapy 支持使用代理服务器来规避反爬虫机制。你可以通过中间件来处理代理。
DOWNLOADER_MIDDLEWARES = {
'scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware': 1,
}
PROXY = 'http://your_proxy_address:port'
5.6 请求重试与错误处理
Scrapy 内置了重试机制,可以通过设置 RETRY_TIMES 来控制最大重试次数。
# 最大重试次数
RETRY_TIMES = 3
如果请求失败,Scrapy 会自动进行重试。
6. 运行爬虫
一旦爬虫开发完成,你可以通过以下命令来启动它:
scrapy crawl myspider
如果要将数据保存到文件中,可以使用 -o 选项:
scrapy crawl myspider -o output.json
7. 总结
Scrapy 是一个非常强大且高效的爬虫框架,适合用来构建大规模的网络数据抓取应用。它不仅支持异步请求、数据管道、代理、请求重试等高级功能,还提供了丰富的配置选项,让开发者可以灵活定制爬虫的行为。通过 Scrapy,你可以高效地抓取、解析、存储和处理来自不同网站的数据。
Scrapy 官网:https://scrapy.org/。
Scrapy 特点与介绍:https://www.runoob.com/w3cnote/scrapy-detail.html。