一、items保存爬取的文件

items.py

import scrapy

class QuoteItem(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
text = scrapy.Field()
author = scrapy.Field()
tags = scrapy.Field()

quote.py

# -*- coding: utf-8 -*-
import scrapy
from toscrapy.items import QuoteItem class QuoteSpider(scrapy.Spider):
name = 'quote'
allowed_domains = ['quotes.toscrape.com']
start_urls = ['http://quotes.toscrape.com/']
"""
知识点
1. text()获取标签的text
2. @属性 获取属性的值
3. extract()查找多个 extract_first() 查找一个
4. response.urljoin url拼接
5. scrapy.Request(url=_next, callback=self.parse) 回调
"""
def parse(self, response):
# print(response.text)
quotes = response.xpath('//div[@class="col-md-8"]/div[@class="quote"]')
# print(quotes)''
for quote in quotes:
# print('=' * 20)
# print(quote)
item = QuoteItem()
# extract_first() 查找一个
text = quote.xpath('.//span[@class="text"]/text()').extract_first()
# print(text)
item['text'] = text
author = quote.xpath('.//span/small[@class="author"]/text()').extract_first()
# print(author)
item['author'] = author
# extract()查找多个
tags = quote.xpath('.//div[@class="tags"]/a[@class="tag"]/@href').extract()
item['tags'] = tags
# print(tags)
yield item
# print('>' * 40)
next_url = response.xpath('//div[@class="col-md-8"]/nav/ul[@class="pager"]/li[@class="next"]/a/@href').extract_first()
# print(next_url)
# 拼接url
_next = response.urljoin(next_url)
# print(_next)
# callback 回调函数
yield scrapy.Request(url=_next, callback=self.parse)

或直接yield QuoteItem()

产生文件命令

scrapy crawl quote -o qutoes.json
scrapy crawl quote -o quotes.jsonlines
or
scrapy crawl quote -o quotes.jl
# 每一个item输出一行json

文件类型:qutoes.xml  qutoes.jl  qutoes.csv等

二、piplines

1、核心:

爬虫每执行一次 yield item对象 -> 执行一次pipelines中的process_item方法(通过修改配置文件使pipelines生效) -> 将数据存入数据库或写入文件

2、settings.py

ITEM_PIPELINES = {
# 后面的参数是不同pipelines类的权重值(0-1000),权重值越小越优先
'toscrapy.pipelines.ToscrapyPipeline': 300,
}

配置settings文件是执行pipeline的前提条件

3、pipelines

a、默认

class ToscrapyPipeline(object):

    def process_item(self, item, spider):
"""
:param item: item对象
:param spider: 爬虫对象
:return:
"""
# print('='*20, item)
return item

b、其它方法

开始爬虫时,调用的方法

    def open_spider(self, spider):
"""
开始爬虫,调用
:param spider:
:return:
"""
pass

爬虫结束时,调用的方法

    def close_spider(self, spider):
"""
关闭爬虫,调用
:param spider:
:return:
"""
pass

from_crawler方法

作用:初始化时,实例化pipleline类对象

目的:将数据储存的路径,写到配置文件中

    @classmethod
def from_crawler(cls, crawler):
"""
初始化方法时,创建pipeline类的对象
:param crawler:
:return:
"""
# crawler.settings 获取全部配置文件
path = crawler.settings.get('FILE_PATH')
# 实例化对象
return cls(path)

c、pipeline类方法分析

判断是否有from_crawler方法

有:obj = pipeline类.from_crawler()

无:obj = pipeline类()

当爬虫开始时,执行 open_spider方法

当爬虫yield item对象时, 执行 process_item方法

当爬虫结束时,执行 close_spider方法

d、序列化

pipelines.py

class ToscrapyPipeline(object):

    def __init__(self, path):
self.f = None
self.path = path @classmethod
def from_crawler(cls, crawler):
"""
初始化方法时,创建pipeline类的对象
:param crawler:
:return:
"""
# crawler.settings 获取全部配置文件
path = crawler.settings.get('FILE_PATH')
# 实例化对象
return cls(path) def open_spider(self, spider):
"""
开始爬虫,调用
:param spider:
:return:
"""
self.f = open(file=self.path, mode='a', encoding="utf-8") def process_item(self, item, spider):
"""
爬虫执行yield item对象,调用
:param item: item对象
:param spider: 爬虫对象
:return:
"""
# print('='*20, item)
self.f.write(item['text'] + '\n')
return item def close_spider(self, spider):
"""
爬虫结束,调用
:param spider:
:return:
"""
self.f.close()

4、多个pipeline类

piplines.py文件中可以有多个类,一个把数据保存到数据库,一个把数据保存到文件

a、执行顺序由settings.py的权重值决定,多个pipeline类中方法的执行顺序可以看成有序的异步

file from_crawl
db from_crawl
file open_spider
db open_spider
file process_item
db process_item
file process_item
db process_item
file process_item
db process_item
db close_spider
file close_spider

b、process_item方法中return item的作用

为下一个pipeline类中的process_item方法提供item

1)、没有返回item

下一个类的item是None

# -*- coding: utf-8 -*-

# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://docs.scrapy.org/en/latest/topics/item-pipeline.html class ToscrapyPipeline(object): def __init__(self, path):
self.f = None
self.path = path @classmethod
def from_crawler(cls, crawler):
"""
初始化方法时,创建pipeline类的对象
:param crawler:
:return:
"""
# crawler.settings 获取全部配置文件
path = crawler.settings.get('FILE_PATH')
# 实例化对象
print('file from_crawl')
return cls(path) def open_spider(self, spider):
"""
开始爬虫,调用
:param spider:
:return:
"""
print('file open_spider')
self.f = open(file=self.path, mode='a', encoding="utf-8") def process_item(self, item, spider):
"""
爬虫执行yield item对象,调用
:param item: item对象
:param spider: 爬虫对象
:return:
"""
print('file process_item')
# self.f.write(item['text'] + '\n')
# return item def close_spider(self, spider):
"""
爬虫结束,调用
:param spider:
:return:
"""
print('file close_spider')
self.f.close() class DBPipeline(object): def __init__(self, path):
self.f = None
self.path = path @classmethod
def from_crawler(cls, crawler):
"""
初始化方法时,创建pipeline类的对象
:param crawler:
:return:
"""
# crawler.settings 获取全部配置文件
path = crawler.settings.get('DB_PATH')
# 实例化对象
print('db from_crawl')
return cls(path) def open_spider(self, spider):
"""
开始爬虫,调用
:param spider:
:return:
"""
print('db open_spider')
self.f = open(file=self.path, mode='a', encoding="utf-8") def process_item(self, item, spider):
"""
爬虫执行yield item对象,调用
:param item: item对象
:param spider: 爬虫对象
:return:
"""
print('db process_item value is {}'.format(item))
# self.f.write(item['text'] + '\n')
return item def close_spider(self, spider):
"""
爬虫结束,调用
:param spider:
:return:
"""
print('db close_spider')
self.f.close()

没有返回item

2)、DropItem

不执行后续pipeline类中的process_item方法

导入

from scrapy.exceptions import DropItem
# -*- coding: utf-8 -*-

# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://docs.scrapy.org/en/latest/topics/item-pipeline.html
from scrapy.exceptions import DropItem class ToscrapyPipeline(object): def __init__(self, path):
self.f = None
self.path = path @classmethod
def from_crawler(cls, crawler):
"""
初始化方法时,创建pipeline类的对象
:param crawler:
:return:
"""
# crawler.settings 获取全部配置文件
path = crawler.settings.get('FILE_PATH')
# 实例化对象
print('file from_crawl')
return cls(path) def open_spider(self, spider):
"""
开始爬虫,调用
:param spider:
:return:
"""
print('file open_spider')
self.f = open(file=self.path, mode='a', encoding="utf-8") def process_item(self, item, spider):
"""
爬虫执行yield item对象,调用
:param item: item对象
:param spider: 爬虫对象
:return:
"""
print('file process_item')
# self.f.write(item['text'] + '\n')
# return item
raise DropItem() def close_spider(self, spider):
"""
爬虫结束,调用
:param spider:
:return:
"""
print('file close_spider')
self.f.close() class DBPipeline(object): def __init__(self, path):
self.f = None
self.path = path @classmethod
def from_crawler(cls, crawler):
"""
初始化方法时,创建pipeline类的对象
:param crawler:
:return:
"""
# crawler.settings 获取全部配置文件
path = crawler.settings.get('DB_PATH')
# 实例化对象
print('db from_crawl')
return cls(path) def open_spider(self, spider):
"""
开始爬虫,调用
:param spider:
:return:
"""
print('db open_spider')
self.f = open(file=self.path, mode='a', encoding="utf-8") def process_item(self, item, spider):
"""
爬虫执行yield item对象,调用
:param item: item对象
:param spider: 爬虫对象
:return:
"""
print('db process_item value is {}'.format(item))
# self.f.write(item['text'] + '\n')
return item def close_spider(self, spider):
"""
爬虫结束,调用
:param spider:
:return:
"""
print('db close_spider')
self.f.close()

DropItem

5、spider参数的作用

作用:pipelines.py中的类和方法是所有爬虫共用的

应用场景:如果先让某个方法,只有一个爬虫可以使用,就要用到spider参数

注意:spider参数对应的是爬虫中的name值

    def open_spider(self, spider):
"""
开始爬虫,调用
:param spider:
:return:
"""
#
if spider == 'quote':
print('file open_spider')
self.f = open(file=self.path, mode='a', encoding="utf-8")

持久化到redis可参考

https://www.cnblogs.com/wanglan/p/10826678.html

使用mongodb参考

https://blog.csdn.net/qq_41020281/article/details/79459604

Scrapy持久化(items+pipelines)的更多相关文章

  1. Scrapy持久化存储

    基于终端指令的持久化存储 保证爬虫文件的parse方法中有可迭代类型对象(通常为列表or字典)的返回,该返回值可以通过终端指令的形式写入指定格式的文件中进行持久化操作; 执行输出指定格式进行存储:将爬 ...

  2. Scrapy持久化存储-爬取数据转义

    Scrapy持久化存储 爬虫爬取数据转义问题 使用这种格式,会自动帮我们转义 'insert into wen values(%s,%s)',(item['title'],item['content' ...

  3. cnblogs 博客爬取 + scrapy + 持久化 + 分布式

    目录 普通 scrapy 分布式爬取 cnblogs_spider.py 普通 scrapy # -*- coding: utf-8 -*- import scrapy from ..items im ...

  4. scrapy持久化到Excel表格

    前提条件: 防止乱码产生 ITEM_PIPELINES = { 'xpc.pipelines.ExcelPipeline': 300, } 方法一 1.安装openpyxl conda install ...

  5. scrapy的使用-Pipelines

    #------------------简单的对item操作方式----------------------------# import json class QsbkPipeline(object): ...

  6. scrapy的持久化相关

    终端指令的持久化存储 保证爬虫文件的parse方法中有可迭代类型对象(通常为列表or字典)的返回,该返回值可以通过终端指令的形式写入指定格式的文件中进行持久化操作. 需求是:将糗百首页中段子的内容和标 ...

  7. scrapy 爬虫框架之持久化存储

    scrapy  持久化存储 一.主要过程: 以爬取校花网为例 : http://www.xiaohuar.com/hua/ 1.  spider    回调函数     返回item 时    要用y ...

  8. scrapy框架的持久化存储

    一 . 基于终端指令的持久化存储 保证爬虫文件的parse方法中有可迭代类型对象(通常为列表or字典)的返回,该返回值可以通过终端指令的形式写入指定格式的文件中进行持久化操作. 执行输出指定格式进行存 ...

  9. (六--二)scrapy框架之持久化操作

    scrapy框架之持久化操作 基于终端指令的持久化存储 基于管道的持久化存储 1 基于终端指令的持久化存储 保证爬虫文件的parse方法中有可迭代类型对象(通常为列表or字典)的返回,该返回值可以通过 ...

随机推荐

  1. P1061 最长连号

    题目描述 输入n个正整数,(1<=n<=10000),要求输出最长的连号的长度.(连号指从小到大连续自然数) 输入格式 第一行,一个数n; 第二行,n个正整数,之间用空格隔开. 输出格式 ...

  2. linux平台依赖性

    每个电脑平台有其自己的特点, 内核设计者可以自由使用所有的特性来获得更好的性能. in the target object file ??? 不象应用程序开发者, 他们必须和预编译的库一起连接他们的代 ...

  3. 解决从旧格式的 csproj 迁移到新格式的 csproj 格式 AssemblyInfo 文件值重复问题

    现在很多小伙伴开始使用了 dotnet core 项目,但是如果是从以前的 dotnet framework 的项目修改为 dotnet core 项目格式,会发现编译的时候出现了 AssemblyI ...

  4. Jmeter完整Demo

    1:创建一个线程组 2:添加一个cookie管理器 3:设置你的信息头管理器:application/json;text/plain;charset=UTF-8 44 4:添加一个用户参数,做全局变量 ...

  5. 节点列表和HTML集合

    getElementsByName()和getElementByTagName()返回的都是NodeList集合. 而document.images和document0.forms的属性为HTMLCo ...

  6. es6笔记 day2---函数默认参数、箭头函数、剩余参数

    函数变化: 1.函数默认参数 2.函数参数默认是已经定义了,不能再使用let.const声明 3.扩展运算符.rest运算符 ...就是扩展运算符,它的作用就是把数组给展开 结合函数使用传参,也可以将 ...

  7. com.netflix.discovery.DiscoveryClient : Completed shut down of DiscoveryClient

    启动报错:com.netflix.discovery.DiscoveryClient    : Completed shut down of DiscoveryClient 解决方案: 添加web主件 ...

  8. Linux基础:Linux下常用命令

    常用命令 shutdown ​ 用来系统关机命令.shutdown指令可以关闭所有程序,并依用户的需要,进行重新开机或关机的动作. ​ shutdown (选项)(参数) -c: 当执行"s ...

  9. ELK学习实验004:Elasticsearch的简单介绍和操作

    一 集群节点 Elstaicsearch的集群是由多个节点组成都,通过cluster.name设置集权名称,比能切用与区分其他的集群,每个节点通过node.name指定节点 在Elasticsearc ...

  10. EasyMock.replay()有什么用

    现在很多项目都使用EasyMock来作为单元测试框架. EasyMock一个方法,基本上是三步:EasyMock.expect().EasyMock.replay().EasyMock.verify( ...