在Scrapy爬虫框架进行数据解析 使用Scrapy内建的Xpath进行数据解析我们已经知道了如何进行数据解析,那么现在就需要进行数据持久化存储,这里有两种方式存储数据,一种是基于终端指令,另一种是基于管道。
基于终端指令存储
在 Scrapy爬虫框架的基本使用 创建spider工程和spider爬虫 scrapy基本命令我已经整理了一些终端的常用命令,里面就有存储的命令,你可以再去看一下。
承接前一篇文章的数据解析,这里我们使用终端命令进行数据存储。需要注意的是,这种方法只可以将parse方法的返回值存储写入到指定后缀的文件中。修改一下parse方法:
# -*- coding: utf-8 -*-
import scrapy
class MeiziSpider(scrapy.Spider):
name = 'meizi'
allowed_domains = ['www.linuxcool.com']
start_urls = ['https://www.linuxcool.com/']
def parse(self, response):
all_list=[]
ul_list=response.xpath('//ul[@class="category-posts"]/li')
for li in ul_list:
# extract() 将列表中的每一个列表元素表示的Selector对象中的字符串取出
href=li.xpath('./a/@href').extract()
# extract()表示将列表中的第0个列表元素进行数据提取
title=li.xpath('./a/text()').extract_first()
dic={
'href':href,
'title':title,
}
all_list.append(dic)
return all_list #返回值就是解析到所有的数据
在终端中执行命令:
scrapy crawl meizi -o meizi.json #保存json文件到本地
该命令只能存储为json、jsonlines、jl、csv、xml、marshal、pickle后缀的文件。
基于管道进行存储
实现流程:
首先第一步已完成,进行第二步,在Item类中也就是items.py文件中定义相关属性,解析的数据有几个字段就定义几个属性:
# -*- coding: utf-8 -*-
import scrapy
class Myspider1Item(scrapy.Item):
# 定义两个属性,是用来存储解析到两个字段的值
href = scrapy.Field()
title = scrapy.Field()
第三步,需要在爬虫文件中实例化Item对象,并将数据封装到Item对象中:
# -*- coding: utf-8 -*-
import scrapy
from myspider1.items import Myspider1Item
class MeiziSpider(scrapy.Spider):
name = 'meizi'
allowed_domains = ['www.linuxcool.com']
start_urls = ['https://www.linuxcool.com/']
# 基于管道的持久化存储
def parse(self, response):
ul_list=response.xpath('//ul[@class="category-posts"]/li')
for li in ul_list:
href=li.xpath('./a/@href').extract_first()
title=li.xpath('./a/text()').extract_first()
# 将解析到的数据存储到Item对象红
item=Myspider1Item()
# item['href']访问item对象中的title属性(只可以这样访问属性)
item['href']=href
item['title']=title
第四步,将存储了解析数据的Item对象提交给管道(pipelines.py):
# -*- coding: utf-8 -*-
import scrapy
from myspider1.items import Myspider1Item
class MeiziSpider(scrapy.Spider):
name = 'meizi'
allowed_domains = ['www.linuxcool.com']
start_urls = ['https://www.linuxcool.com/']
# 基于管道的持久化存储
def parse(self, response):
ul_list=response.xpath('//ul[@class="category-posts"]/li')
for li in ul_list:
href=li.xpath('./a/@href').extract()
title=li.xpath('./a/text()').extract_first()
# 将解析到的数据存储到Item对象红
item=Myspider1Item()
# item['href']访问item对象中的title属性(只可以这样访问属性)
item['href']=href
item['title']=title
# 将item对象提交给管道(pipelines.py定义好了管道类)
yield item
第五步,在管道文件中接收Item对象,使用process_item方法进行接收:
# -*- coding: utf-8 -*-
class Myspider1Pipeline:
# 这个方法是用来接受爬虫文件提交过来的item对象(一次只能接收一个item对象)
# 参数item:就是接收到的item对象
def process_item(self, item, spider):
# 将接收到的item对象写入文件
href=item['href'] #将item对象中存储的值取出
title=item['title']
# open('./a.txt') 写在此处是错误的,因为process_item方法会被调用多次
return item
在process_item方法中不能进行文件打开操作,process_item一次只能接收一个item对象,而我们的爬虫返回很多的item对象,所以process_item会执行多次,也就是文件会打开多次,这是不允许的。在管道中给我们提供了open_spider方法和close_spider方法,前者只会在爬虫开始后被执行一次,后者只会在爬虫结束前调用一次,如果想了解更多内容参考:Scrapy深入学习pipelines管道文件,这里就解释这么多:
# -*- coding: utf-8 -*-
class Myspider1Pipeline:
# 重写父类的方法:只会在爬虫开始后被执行一次
def open_spider(self,spider):
print('I am open_spider()')
self.file=open('./meizi.txt','w',encoding='utf-8')
# 这个方法是用来接受爬虫文件提交过来的item对象(一次只能接收一个item对象)
# 参数item:就是接收到的item对象
def process_item(self, item, spider):
print('I am process_item()')
# 将接收到的item对象写入文件
href=item['href'] #将item对象中存储的值取出
title=item['title']
self.file.write(href+':'+title+'\n')
return item
# 重写父类的方法:只会在爬虫结束前调用一次
def close_spider(self,spider):
print('I am close_spider()')
self.file.close()
最后一步,在settings.py文件中开启管道:
ITEM_PIPELINES = {
# 300表示优先级,数值越小优先级越高
'myspider1.pipelines.Myspider1Pipeline': 300,
}
你可以看到这是对我们的管道类进行注册,这样才可以使用我们的Myspider1Pipeline,300表示优先级,数值越小优先级越高。这样运行我们的爬虫文件,你会发现I am open_spider()在爬虫开始的时候打印一次,I am process_item()打印多次,I am close_spider()在爬虫结束的时候打印一次。
2. 本站不保证所提供下载的资源的准确性、安全性和完整性,资源仅供下载学习之用!如有链接无法下载、失效或广告,请联系客服处理!
3. 您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容资源!如用于商业或者非法用途,与本站无关,一切后果请用户自负!