在当今数字化时代,网络爬虫技术已成为数据获取的重要手段。Python凭借其简洁的语法和丰富的生态系统,成为网络爬虫开发的首选语言。在众多Python爬虫工具中,Scrapy作为一个强大的爬虫框架,以其高性能、可扩展性和易用性著称,深受开发者青睐。

Scrapy框架概述
Scrapy是一个基于Twisted异步网络框架开发的爬虫框架,专门用于大规模网页数据提取。它采用事件驱动的网络编程模式,能够高效处理并发请求,是构建网络爬虫的理想选择。
主要特点:
- 异步网络请求:基于Twisted框架,支持异步I/O,大幅提升爬取效率
- 中间件系统:可自定义处理请求和响应的中间件,实现更灵活的数据处理
- 内置Pipeline:支持数据清洗、验证和存储的管道机制
- 分布式支持:可通过Redis等组件实现分布式爬取
- 自动重试:智能处理请求失败的情况
- 导出多种格式:支持JSON、CSV、XML等多种数据导出格式
安装与环境配置
首先,我们需要安装Scrapy框架。推荐使用pip包管理器进行安装:
pip install scrapy
对于Windows用户,可能需要先安装一些依赖:
pip install pywin32
pip install twisted
Scrapy项目结构
创建一个新的Scrapy项目:
scrapy startproject tutorial
cd tutorial
这会生成如下项目结构:
tutorial/
├── scrapy.cfg # 项目配置文件
└── tutorial/ # 项目Python模块
├── __init__.py
├── items.py # 项目项目定义
├── middlewares.py # 中间件定义
├── pipelines.py # 管道文件
├── settings.py # 设置文件
└── spiders/ # 放置spider代码的目录
└── __init__.py
实战示例:构建图书信息爬虫
让我们以爬取某在线书店的图书信息为例,展示Scrapy的使用方法。
第一步:定义数据模型
在items.py
中定义要抓取的数据结构:
import scrapy
class BookItem(scrapy.Item):
title = scrapy.Field() # 书名
author = scrapy.Field() # 作者
price = scrapy.Field() # 价格
description = scrapy.Field() # 描述
isbn = scrapy.Field() # ISBN号
第二步:创建爬虫
在spiders
目录下创建新文件books_spider.py
:
import scrapy
from tutorial.items import BookItem
class BooksSpider(scrapy.Spider):
name = 'books' # 爬虫的唯一标识
# 这里使用示例网站,实际使用时请替换为目标网站
start_urls = ['http://books.toscrape.com/']
def parse(self, response):
# 获取每本书的链接
for book in response.css('article.product_pod'):
book_url = book.css('h3 a::attr(href)').get()
yield response.follow(book_url, self.parse_book)
# 处理下一页
next_page = response.css('li.next a::attr(href)').get()
if next_page is not None:
yield response.follow(next_page, self.parse)
def parse_book(self, response):
book = BookItem()
book['title'] = response.css('h1::text').get()
book['price'] = response.css('p.price_color::text').get()
book['description'] = response.css('#product_description + p::text').get()
# 提取表格中的信息
rows = response.css('table tr')
for row in rows:
heading = row.css('th::text').get()
if heading == 'Author':
book['author'] = row.css('td::text').get()
elif heading == 'ISBN':
book['isbn'] = row.css('td::text').get()
yield book
第三步:配置数据处理管道
在pipelines.py
中添加数据处理逻辑:
import json
class JsonWriterPipeline:
def open_spider(self, spider):
self.file = open('books.json', 'w')
def close_spider(self, spider):
self.file.close()
def process_item(self, item, spider):
line = json.dumps(dict(item)) + "\n"
self.file.write(line)
return item
第四步:配置设置
在settings.py
中启用管道:
ITEM_PIPELINES = {
'tutorial.pipelines.JsonWriterPipeline': 300,
}
# 添加请求头,模拟浏览器行为
USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
# 控制请求延迟,避免对服务器造成压力
DOWNLOAD_DELAY = 1
第五步:运行爬虫
在项目根目录下执行:
scrapy crawl books
高级功能展示
1. 使用中间件处理请求
class CustomUserAgentMiddleware:
def process_request(self, request, spider):
user_agents = [
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) ...',
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) ...',
'Mozilla/5.0 (iPhone; CPU iPhone OS 14_4 like Mac OS X) ...'
]
request.headers['User-Agent'] = random.choice(user_agents)
2. 实现图片下载
from scrapy.pipelines.images import ImagesPipeline
class BookImagePipeline(ImagesPipeline):
def get_media_requests(self, item, info):
if item['image_url']:
yield scrapy.Request(item['image_url'])
def file_path(self, request, response=None, info=None):
return f'full/{request.url.split("/")[-1]}'
3. 使用Item Loader简化数据提取
from scrapy.loader import ItemLoader
from scrapy.loader.processors import TakeFirst, Join
class BookLoader(ItemLoader):
default_output_processor = TakeFirst()
description_out = Join()
def parse_book(self, response):
loader = BookLoader(item=BookItem(), response=response)
loader.add_css('title', 'h1::text')
loader.add_css('price', 'p.price_color::text')
loader.add_css('description', '#product_description + p::text')
return loader.load_item()
性能优化建议
- 合理设置CONCURRENT_REQUESTS参数控制并发量
- 使用DOWNLOAD_DELAY避免请求过于频繁
- 启用HTTPCACHE_ENABLED缓存已爬取的页面
- 使用ROBOTSTXT_OBEY遵守网站爬虫协议
- 实现自定义重试机制处理异常情况
请始终注意:
- 遵守网站的robots.txt规范
- 合理控制爬取频率
- 遵守网站的使用条款
- 注意数据的合法使用
相关资源
- PyPI地址:https://pypi.org/project/Scrapy/
- GitHub仓库:https://github.com/scrapy/scrapy
- 官方文档:https://docs.scrapy.org/
关注我,每天推荐一款实用的Python爬虫工具
