Scrapy爬虫框架进行数据的持久化存储 基于终端指令 基于管道存储

鳄鱼君

发表文章数:643

Vieu四代商业主题

高扩展、安全、稳定、响应式布局多功能模板。

¥69 现在购买
首页 » Python » Scrapy爬虫框架进行数据的持久化存储 基于终端指令 基于管道存储

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后缀的文件

基于管道进行存储

实现流程:

1、在爬虫文件中解析数据
2、在Item类中定义相关的属性(items.py)
3、将在爬虫文件中解析的数据存储封装到Item对象中
4、将存储了解析数据的Item对象提交给管道
5、在管道文件中接收Item对象,且对其进行任意形式的持久化存储操作
6、在配置文件中开启管道

首先第一步已完成,进行第二步,在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()在爬虫结束的时候打印一次。

未经允许不得转载:作者:鳄鱼君, 转载或复制请以 超链接形式 并注明出处 鳄鱼君
原文地址:《Scrapy爬虫框架进行数据的持久化存储 基于终端指令 基于管道存储》 发布于2020-05-09

分享到:
赞(0) 赏杯咖啡

评论 抢沙发

1 + 4 =


文章对你有帮助可赏作者一杯咖啡

支付宝扫一扫打赏

微信扫一扫打赏

Vieu4.6主题
专业打造轻量级个人企业风格博客主题!专注于前端开发,全站响应式布局自适应模板。
切换注册

登录

忘记密码 ?

您也可以使用第三方帐号快捷登录

Q Q 登 录
微 博 登 录
切换登录

注册