第154集 Scrapy框架基础
1 什么是Scrapy?
Scrapy是一个用于爬取网站数据、提取结构化信息的Python框架。它提供了一套强大的工具和机制,使得开发者能够快速、高效地编写网络爬虫。
Scrapy的主要特点:
- 基于事件驱动的异步处理
- 内置数据提取机制(XPath和CSS选择器)
- 强大的扩展功能
- 内置支持数据存储(JSON、CSV、XML等)
- 自动处理请求并发
- 内置反爬虫机制支持
2 Scrapy的安装
在使用Scrapy之前,我们需要先安装它。
pip install scrapy3 Scrapy的基本架构
Scrapy采用了模块化的架构设计,主要包含以下组件:
- **引擎(Engine)**:负责控制数据流在各个组件之间的流动
- **调度器(Scheduler)**:管理待爬取的请求队列
- **下载器(Downloader)**:下载网页内容
- **爬虫(Spider)**:定义爬取规则和数据提取逻辑
- **项目管道(Item Pipeline)**:处理爬取到的数据
- **下载器中间件(Downloader Middleware)**:处理请求和响应
- **爬虫中间件(Spider Middleware)**:处理爬虫的输入(响应)和输出(请求和项目)
4 创建第一个Scrapy项目
4.1 创建项目
使用Scrapy命令行工具创建一个新的项目:
scrapy startproject myspider这将创建一个名为myspider的目录,包含以下结构:
myspider/
├── scrapy.cfg # 项目配置文件
└── myspider/ # 项目的Python模块
├── __init__.py
├── items.py # 定义项目的数据模型
├── middlewares.py# 中间件定义
├── pipelines.py # 项目管道
├── settings.py # 项目设置
└── spiders/ # 存储爬虫的目录
└── __init__.py4.2 创建爬虫
在spiders目录下创建一个新的爬虫文件:
cd myspider
scrapy genspider example example.com这将在spiders目录下创建一个名为example.py的爬虫文件,内容如下:
import scrapy
class ExampleSpider(scrapy.Spider):
name = "example"
allowed_domains = ["example.com"]
start_urls = ["http://example.com/"]
def parse(self, response):
pass5 Scrapy爬虫的基本结构
5.1 爬虫类定义
一个基本的Scrapy爬虫包含以下几个部分:
import scrapy
class MySpider(scrapy.Spider):
# 爬虫名称,必须唯一
name = "myspider"
# 允许爬取的域名列表
allowed_domains = ["example.com"]
# 起始URL列表
start_urls = ["http://example.com/page1", "http://example.com/page2"]
# 解析响应的方法
def parse(self, response):
# 在这里编写解析逻辑
pass5.2 解析响应
Scrapy提供了两种主要的方式来解析响应内容:XPath和CSS选择器。
使用XPath
def parse(self, response):
# 使用XPath选择器提取数据
titles = response.xpath('//h1/text()').getall()
for title in titles:
print(title)
# 提取单个元素
single_title = response.xpath('//h1/text()').get()
if single_title:
print(f"单个标题: {single_title}")
# 提取属性值
links = response.xpath('//a/@href').getall()
for link in links:
print(f"链接: {link}")使用CSS选择器
def parse(self, response):
# 使用CSS选择器提取数据
titles = response.css('h1::text').getall()
for title in titles:
print(title)
# 提取单个元素
single_title = response.css('h1::text').get()
if single_title:
print(f"单个标题: {single_title}")
# 提取属性值
links = response.css('a::attr(href)').getall()
for link in links:
print(f"链接: {link}")6 提取数据并创建Item
6.1 定义Item
在items.py文件中定义数据模型:
import scrapy
class MyspiderItem(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
title = scrapy.Field()
link = scrapy.Field()
description = scrapy.Field()6.2 在爬虫中使用Item
import scrapy
from myspider.items import MyspiderItem
class ExampleSpider(scrapy.Spider):
name = "example"
allowed_domains = ["example.com"]
start_urls = ["http://example.com/"]
def parse(self, response):
# 创建Item对象
item = MyspiderItem()
# 提取数据并填充Item
item['title'] = response.css('h1::text').get()
item['link'] = response.url
item['description'] = response.css('meta[name="description"]::attr(content)').get()
# 返回Item
yield item
# 或者返回多个Item
for article in response.css('.article'):
article_item = MyspiderItem()
article_item['title'] = article.css('h2::text').get()
article_item['link'] = article.css('a::attr(href)').get()
article_item['description'] = article.css('p::text').get()
yield article_item7 跟进链接
Scrapy允许我们在解析响应时提取新的链接,并跟进这些链接继续爬取。
def parse(self, response):
# 解析当前页面的数据
# ...
# 提取下一页链接并跟进
next_page = response.css('a.next-page::attr(href)').get()
if next_page:
# 绝对URL
if next_page.startswith('http'):
next_url = next_page
# 相对URL,转换为绝对URL
else:
next_url = response.urljoin(next_page)
# 发送新的请求并指定回调函数
yield scrapy.Request(next_url, callback=self.parse)
# 或者使用更简洁的方式
for href in response.css('a.article-link::attr(href)'):
yield response.follow(href, callback=self.parse_article)
# 处理文章详情页的回调函数
def parse_article(self, response):
item = MyspiderItem()
item['title'] = response.css('h1.article-title::text').get()
item['content'] = response.css('div.article-content::text').getall()
yield item8 运行Scrapy爬虫
8.1 使用命令行运行爬虫
# 进入项目目录
cd myspider
# 运行爬虫
scrapy crawl example8.2 保存爬取结果
# 保存为JSON格式
scrapy crawl example -o items.json
# 保存为CSV格式
scrapy crawl example -o items.csv
# 保存为XML格式
scrapy crawl example -o items.xml9 Scrapy设置
9.1 基本设置
在settings.py文件中可以配置Scrapy的各种参数:
# 爬虫名称
BOT_NAME = 'myspider'
# 爬虫模块
SPIDER_MODULES = ['myspider.spiders']
NEWSPIDER_MODULE = 'myspider.spiders'
# 遵循robots.txt规则
ROBOTSTXT_OBEY = True
# 并发请求数
CONCURRENT_REQUESTS = 32
# 下载延迟
DOWNLOAD_DELAY = 1
# 禁用cookies
COOKIES_ENABLED = False
# 用户代理
USER_AGENT = 'myspider (+http://www.example.com)'
# 项目管道
ITEM_PIPELINES = {
'myspider.pipelines.MyspiderPipeline': 300,
}10 项目管道
项目管道用于处理爬取到的数据,例如清理、验证、存储等操作。
10.1 定义管道
在pipelines.py文件中定义管道:
class MyspiderPipeline:
def process_item(self, item, spider):
# 处理数据
if item['title']:
item['title'] = item['title'].strip()
# 返回处理后的item
return item10.2 启用管道
在settings.py中启用管道:
ITEM_PIPELINES = {
'myspider.pipelines.MyspiderPipeline': 300,
}数字表示管道的执行顺序,数值越小,执行优先级越高。
11 实际案例:爬取书籍信息
11.1 创建项目和爬虫
# 创建项目
scrapy startproject bookspider
# 进入项目目录
cd bookspider
# 创建爬虫
scrapy genspider books example.com11.2 定义Item
在items.py中定义数据模型:
import scrapy
class BookspiderItem(scrapy.Item):
# 书籍标题
title = scrapy.Field()
# 书籍价格
price = scrapy.Field()
# 书籍评分
rating = scrapy.Field()
# 书籍链接
link = scrapy.Field()11.3 编写爬虫
在spiders/books.py中编写爬虫逻辑:
import scrapy
from bookspider.items import BookspiderItem
class BooksSpider(scrapy.Spider):
name = "books"
allowed_domains = ["books.toscrape.com"]
start_urls = ["http://books.toscrape.com/"]
def parse(self, response):
# 提取所有书籍信息
for book in response.css('.product_pod'):
item = BookspiderItem()
# 提取书籍标题
item['title'] = book.css('h3 a::attr(title)').get()
# 提取书籍价格
item['price'] = book.css('.price_color::text').get()
# 提取书籍评分
rating_classes = book.css('.star-rating::attr(class)').get()
rating = rating_classes.split()[-1] if rating_classes else 'No rating'
item['rating'] = rating
# 提取书籍链接
item['link'] = response.urljoin(book.css('h3 a::attr(href)').get())
yield item
# 提取下一页链接并跟进
next_page = response.css('li.next a::attr(href)').get()
if next_page:
yield response.follow(next_page, callback=self.parse)11.4 运行爬虫
scrapy crawl books -o books.json12 总结
通过本集的学习,我们掌握了Scrapy框架的基础知识,包括:
- Scrapy的基本概念和架构
- 创建和运行Scrapy项目
- 编写基本的爬虫
- 使用XPath和CSS选择器提取数据
- 定义和使用Item
- 跟进链接继续爬取
- 配置Scrapy设置
- 使用项目管道处理数据
- 实际案例:爬取书籍信息
Scrapy是一个功能强大的爬虫框架,它提供了完整的爬取流程支持,使得我们能够快速、高效地开发各种网络爬虫。下一集我们将深入学习Scrapy爬虫的编写技巧。