一、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. UVA 1625 "Color Length" (基础DP)

    传送门 •参考资料 [1]:HopeForBetter •题意 •题解(by 紫书) •我的理解 用了一上午的时间,参考紫书+上述博文,终于解决了疑惑: 定义第一个颜色序列用串 s 表示,第二个用串 ...

  2. H3C DHCP简介

  3. P1014 高精度减法

    题目描述 给你两个很大的正整数A和B,你需要计算他们的差. 输入格式 输入一行包含两个正整数A和B,以一个空格分隔(A和B的位数都不超过 \(10^5\) ,但是B有可能比A大) 输出格式 输出一行包 ...

  4. gu集合

    离散型随机变量的一切可能的取值  与对应的概率  乘积之和称为该离散型随机变量的数学期望,本题期望是概率乘得分之和 数列是递增的,可以枚举第二小的数,假设选第i个数为第2小的数,则第1小的数有i-1种 ...

  5. git 通过 SublimeMerge 处理冲突

    在使用 Git 的时候,如果是多个小伙伴开发,那么如果同时修改一个文件将出现冲突.也就是在自动合并的时候不知道使用哪个代码才对,此时就需要合并工具的协助.我找了很久发现 SublimeMerge 是界 ...

  6. 使用 HttpClient 进行表单提交时,遇到的问题

    问题 在开发微信支付的小微商户进件接口时,需要通过表单来上传身份证图片等数据.在微信支付接口文档也说明了,需要使用 multipart/form-data 的方式发送请求..NET 提供了 Multi ...

  7. 22.re(正则表达式)

    转载:https://www.cnblogs.com/yuanchenqi/article/5732581.html 就其本质而言,正则表达式(或 RE)是一种小型的.高度专业化的编程语言,(在Pyt ...

  8. mac如何查看已连接wifi的密码

    可以通道mac自带的“钥匙串访问”功能查看.选择需要查询的wifi名称,右击选择“将密码拷贝到剪贴板”,输入管理员密码后,密码就拷贝好了. 找个地方粘贴即可看到密码

  9. lombok工作原理分析

    在Lombok使用的过程中,只需要添加相应的注解,无需再为此写任何代码.但是自动生成的代码到底是如何产生的呢? 核心之处就是对于注解的解析上.JDK5引入了注解的同时,也提供了两种解析方式. 运行时解 ...

  10. 【他山之石】mybatis打印sql日志 相关配置

    背景:mybatis的sql日志打印对我来说一直比较迷,哪怕看过网上很多博客后还是这样,这两天刚好又遇到了问题,要查sql不得已又来查阅,这次终于搞定了. mybatis是有提供日志功能支持的,目前支 ...