scrapy框架入门
高性能的持久化存储,高性能的数据解析,分布式。
使用
- 安装:
pip install scrapy
- 创建项目:
scrapy startproject yourProjectName
bash
story_spider/
scrapy.cfg # 部署配置文件
story_spider/ # Python模块,代码写在这个目录下
__init__.py
items.py # 项目项定义文件
pipelines.py # 项目管道文件
settings.py # 项目设置文件
spiders/ # 我们的爬虫/蜘蛛 目录
__init__.py
在spiders目录中创建一个爬虫文件
cd 项目目录
(spriders文件夹所在的目录)scrapy genspider storyxc storyxc.com
爬虫文件内容
pythonimport scrapy # 必须继承scrapy.Spider class StoryxcSpider(scrapy.Spider): # 爬虫文件的名称:爬虫源文件的一个唯一标识 name = 'storyxc' # 允许的域名:用来限定start_urls列表中哪些url可以进行请求发送 allowed_domains = ['storyxc.com'] # 起始的url列表,该列表中存放的url会被scrapy自动进行请求的发送 start_urls = ['https://www.storyxc.com/', 'http://blog.storyxc.com'] # 用作数据解析:response参数表示的是请求成功后的响应对象 def parse(self, response): print(response)
修改settings.py中的ROBOTSTXT_OBEY = False
执行工程命令后可以加 --nolog
也可以在setting.py中添加:
#显示指定级别的日志信息 LOG_LEVEL = 'ERROR'
执行工程
scrapy crawl storyxc
,日志信息bash<200 https://www.storyxc.com/> <200 https://blog.storyxc.com/>
scrapy数据解析
解析糗事百科段子的作者和段子内容
python
import scrapy
# 必须继承scrapy.Spider
class StoryxcSpider(scrapy.Spider):
# 爬虫文件的名称:爬虫源文件的一个唯一标识
name = 'storyxc'
# 允许的域名:用来限定start_urls列表中哪些url可以进行请求发送
# allowed_domains = ['storyxc.com']
# 起始的url列表,该列表中存放的url会被scrapy自动进行请求的发送
start_urls = ['https://www.qiushibaike.com/text/']
# 用作数据解析:response参数表示的是请求成功后的响应对象
def parse(self, response):
# 解析:作者的名称+段子内容
div_list = response.xpath('//div[@id="content"]/div/div[2]/div')
for div in div_list:
# extract()方法可以提取Selector对象中的data参数字符串
# extract_first()提取的是list数组里面的第一个字符串,
author = div.xpath('./div[1]/a[2]/h2/text()').extract_first()
# 列表调用了extract()表示将每一个Selector对象中的data字符串提取出来
content = ''.join(div.xpath('./a[1]/div[1]/span//text()').extract())
print(author,content)
基于终端指令持久化存储
代码改造:
python
import scrapy
# 必须继承scrapy.Spider
class StoryxcSpider(scrapy.Spider):
# 爬虫文件的名称:爬虫源文件的一个唯一标识
name = 'storyxc'
# 允许的域名:用来限定start_urls列表中哪些url可以进行请求发送
# allowed_domains = ['storyxc.com']
# 起始的url列表,该列表中存放的url会被scrapy自动进行请求的发送
start_urls = ['https://www.qiushibaike.com/text/']
# 用作数据解析:response参数表示的是请求成功后的响应对象
def parse(self, response):
# 解析:作者的名称+段子内容
div_list = response.xpath('//div[@id="content"]/div/div[2]/div')
data_list = []
for div in div_list:
# extract()方法可以提取Selector对象中的data参数字符串
# extract_first()提取的是list数组里面的第一个字符串,
author = div.xpath('./div[1]/a[2]/h2/text()').extract_first()
# 列表调用了extract()表示将每一个Selector对象中的data字符串提取出来
content = ''.join(div.xpath('./a[1]/div[1]/span//text()').extract())
dict = {
'author':author,
'content':content
}
data_list.append(dict)
return data_list
- 只能将parse方法返回的内容存储到本地文件中
- 持久化存储的格式只有'json', 'jsonlines', 'jl', 'csv', 'xml', 'marshal', 'pickle'
- 指令:
scrapy crawl xxx -o path
基于管道持久化存储
流程:
数据解析
在item类中定义相关的属性
- fieldName = scrapy.Field()
将解析的数据封装存储到Item类型的对象中
将item类型的对象提交给管道进行持久化存储的操作
在管道类的process_item函数中要将其接受到的item对象中存储的数据进行持久化操作
在settings.py中开启管道
代码改造
Python
import scrapy
from story_spider.items import StorySpiderItem
# 必须继承scrapy.Spider
class StoryxcSpider(scrapy.Spider):
# 爬虫文件的名称:爬虫源文件的一个唯一标识
name = 'storyxc'
# 允许的域名:用来限定start_urls列表中哪些url可以进行请求发送
# allowed_domains = ['storyxc.com']
# 起始的url列表,该列表中存放的url会被scrapy自动进行请求的发送
start_urls = ['https://www.qiushibaike.com/text/']
# 用作数据解析:response参数表示的是请求成功后的响应对象
def parse(self, response):
# 解析:作者的名称+段子内容
div_list = response.xpath('//div[@id="content"]/div/div[2]/div')
data_list = []
for div in div_list:
# extract()方法可以提取Selector对象中的data参数字符串
# extract_first()提取的是list数组里面的第一个字符串,
author = div.xpath('./div[1]/a[2]/h2/text()').extract_first()
# 列表调用了extract()表示将每一个Selector对象中的data字符串提取出来
content = ''.join(div.xpath('./a[1]/div[1]/span//text()').extract())
item = StorySpiderItem()
item['author'] = author
item['content'] = content
yield item
items模块
python
import scrapy
class StorySpiderItem(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
author = scrapy.Field()
content = scrapy.Field()
pipelines模块
python
class StorySpiderPipeline:
fp = None
# open_spider方法只会在爬虫开始时调用一次,可以用于数据初始化操作
def open_spider(self, spider):
print('开始执行爬虫...')
self.fp = open('./qiubai.txt', 'w', encoding='utf-8')
# close_spider会在结束时调用一次
def close_spider(self, spider):
print('爬虫执行结束...')
self.fp.close()
# 专门用来处理item对象
# 该方法可以接收爬虫文件提交的item对象
def process_item(self, item, spider):
author = item['author']
content = item['content']
self.fp.write(author + ':' + content + '\n')
return item
TIP
return item可以使item继续传递到下一个即将被执行的管道类中,以此可以实现多个管道类的操作,比如一份数据持久化到文件,一份数据持久化到数据库
配置文件中开启管道
settings.py中修改
python
# Configure item pipelines
# See https://docs.scrapy.org/en/latest/topics/item-pipeline.html
ITEM_PIPELINES = {
# 300表示优先级,数值越小,优先级越高
'story_spider.pipelines.StorySpiderPipeline': 300,
}
执行爬虫
python
scrapy crawl storyxc
开始执行爬虫...
爬虫执行结束...
目录下生成了qiubai.txt