综述
本系列文档用于对Python爬虫技术的学习进行简单的教程讲解,巩固自己技术知识的同时,万一一不小心又正好对你有用那就更好了。
Python 版本是3.7.4
上一篇文章我们简单入门了Scrapy框架,并且使用Scrapy框架实现了一个爬虫项目。这一篇我们就详细的介绍一下Scrapy框架中的pipeline使用方法(虽然上篇文章我们也稍微详细的讲了pipeline存储数据的优化方式,这篇我们主要讲解如果一个项目多个爬虫,如何使用一个pipeline进行接收数据的问题)。
pipeline核心方法
我们可以自定义Pipeline,只需要实现指定的方法,其中必须要实现的一个方法是:process_item(item, spider)
。
另外还有如下几个比较实用的方法:
- open_spider(spider)
- close_spider(spider)
- close_spider()方法是在Spider关闭的时候自动调用的。在这里我们可以做一些收尾工作,如关闭数据库连接等。其中,参数spider就是被关闭的Spider对象。
- from_crawler(cls, crawler)
process_item(item, spider)
process_item()是必须要实现的方法,被定义的ItemPipeline会默认调用这个方法对Item进行处理。比如,我们可以进行数据处理或者将数据写入到数据库等操作。它必须返回Item类型的值或者抛出一个DropItem异常
close_spider(spider)
open_spider()方法是在Spider开启的时候被自动调用的。在这里我们可以做一些初始化操作,如开启数据库连接等。其中,参数spider就是被开启的Spider对象。
close_spider(spider)
close_spider()方法是在Spider关闭的时候自动调用的。在这里我们可以做一些收尾工作,如关闭数据库连接等。其中,参数spider就是被关闭的Spider对象。
from_crawler(cls, crawler)
from_crawler()方法是一个类方法,用@classmethod标识,是一种依赖注入的方式。它的参数是crawler,通过crawler对象,我们可以拿到Scrapy的所有核心组件,如全局配置的每个信息,然后创建一个Pipeline实例。参数cls就是Class,最后返回一个Class实例。
使用pipeline
从pipeline的字典形式可以看出来,pipeline可以有多个,而且确实pipeline能够定义多个。
为什么需要多个pipeline:
- 一个spider的内容可能要做不同的操作,比如存入不同的数据库中
- 可能会有多个spider,不同的pipeline处理不同的item的内容
注意:
- 使用pipeline需要在setting.py中进行配置
- pipeline的权重值越小优先级越高
- pipeline中process_item不能修改为其他名称
一个spider多个item类型结构情况
我们使用命令创建一个spider程序:
scrapy genspider qsbk_spider qiushibaike.com
将需要配置的信息配置好,这里不再说明。然后在qsbk_spider.py中写入如下代码:
import scrapy
class QsbkSpiderSpider(scrapy.Spider):
name = 'qsbk_spider'
allowed_domains = ['qiushibaike.com']
start_urls = ['http://qiushibaike.com/']
def parse(self, response):
item = {}
# 我们进行奇数偶数的不同参数处理
for i in range(0, 50):
if (i % 2) == 0:
# 偶数处理
item['come_from'] = 'oushu'
item['data'] = i
else:
# 奇数处理
item['come_from'] = 'jishu'
item['data'] = i
yield item
然后再pipelines.py中写入如下代码:
class MyspiderPipeline(object):
def process_item(self, item, spider):
# 增加if判断传来的item是什么数据,然后进行相对应的逻辑判断
if item['come_from'] == 'jishu':
# code..
print('%d 是奇数' % item['data'])
else:
# code ..
print('%d 是偶数' % item['data'])
return item
运行成功即可查看效果。或者在pipeline定义多个类,代码如下:
class MyspiderPipeline(object):
def process_item(self, item, spider):
# 增加if判断传来的item是什么数据,然后进行相对应的逻辑判断
if item['come_from'] == 'jishu':
# code..
print('%d 是奇数' % item['data'])
return item
class MyspiderPipeline1(object):
def process_item(self, item, spider):
# 增加if判断传来的item是什么数据,然后进行相对应的逻辑判断
if item['come_from'] == 'oushu':
# code..
print('%d 是偶数' % item['data'])
return item
然后再配置文件中配置:
ITEM_PIPELINES = {
'mySpider.pipelines.MyspiderPipeline': 300,
'mySpider.pipelines.MyspiderPipeline1': 301,
}
运行可以查看到同样的效果。
多个spider情况
多个spider我们也可以使用上面的那种方式进行处理,再item中增加数据标识,然后根据标识进行不同的处理。除上述外,我们还可以使用另一种方式判断。具体使用方法如下:
我分别使用三个命令创建了三个spider程序:
# 爬取糗百的“文字”模块
scrapy genspider qsbk1_spider qiushibaike.com
# 爬取糗百的“糗图”模块
scrapy genspider qsbk2_spider qiushibaike.com
# 爬取糗百的“穿越模块”
scrapy genspider qsbk3_spider qiushibaike.com
分别运行完三条创建爬虫命令之后,你会在spider文件夹下发现新增了qsbk1_spider.py
、qsbk2_spider.py
、qsbk3_spider.py
三个文件,这就是我们新建的三个爬虫模块文件(项目目录结构就不在这里贴了)。可以通过命令scrapy list
查看项目中创建的爬虫列表。
在三个文件中分别写入如下代码:
- qsbk1_spider.py
import scrapy class Qsbk1SpiderSpider(scrapy.Spider): name = 'qsbk1_spider' allowed_domains = ['qiushibaike.com'] start_urls = ['https://www.qiushibaike.com/text/'] def parse(self, response): item = {} # 这是qsbk1_spider返回的数据 for i in range(0, 10): item['come_from'] = 'qsbk1' item['data'] = i yield item
- qsbk2_spider.py
import scrapy class Qsbk2SpiderSpider(scrapy.Spider): name = 'qsbk2_spider' allowed_domains = ['qiushibaike.com'] start_urls = ['https://www.qiushibaike.com/pic/'] def parse(self, response): item = {} # 这是qsbk2_spider返回的数据 for i in range(10, 20): item['come_from'] = 'qsbk2' item['data'] = i yield item
- qsbk3_spider.py
import scrapy class Qsbk3SpiderSpider(scrapy.Spider): name = 'qsbk3_spider' allowed_domains = ['qiushibaike.com'] start_urls = ['https://www.qiushibaike.com/history/'] def parse(self, response): item = {} # 这是qsbk3_spider返回的数据 for i in range(20, 30): item['come_from'] = 'qsbk3' item['data'] = i yield item
最后三个爬虫爬取的数据都放到了pipeline中,这就需要我们在pipeline中进行判断是那个爬虫传过来的数据。pipelines.py代码如下:
class MyspiderPipeline(object):
def process_item(self, item, spider):
# 这是我们可以根据spider来进行判断
if spider.name == 'qsbk1_spider':
print("这是qsbk1的数据:", item)
elif spider.name == 'qsbk2_spider':
print("这是qsbk2的数据:", item)
elif spider.name == 'qsbk3_spider':
print("这是qsbk3的数据:", item)
else:
print('未知数据')
return item
运行爬虫即可看到相应的打印效果。
使用多个items进行区分
编写items.py代码如下:
import scrapy
class Qsbk1Item(scrapy.Item):
"""
qsbk1爬虫items类
"""
num = scrapy.Field()
class Qsbk2Item(scrapy.Item):
"""
qsbk2爬虫items类
"""
num = scrapy.Field()
class Qsbk3Item(scrapy.Item):
"""
qsbk3爬虫items类
"""
num = scrapy.Field()
编写qsbk1_spider.py代码如下(其他两个爬虫类似):
import scrapy
# 引入对应的items类
from mySpider.items import Qsbk1Item
class Qsbk1SpiderSpider(scrapy.Spider):
name = 'qsbk1_spider'
allowed_domains = ['qiushibaike.com']
start_urls = ['https://www.qiushibaike.com/text/']
def parse(self, response):
for i in range(0, 10):
item = Qsbk1Item(num=i)
yield item
编写pipeline.py代码如下:
# 引入对应的items类
from mySpider.items import Qsbk1Item
from mySpider.items import Qsbk2Item
from mySpider.items import Qsbk3Item
class MyspiderPipeline(object):
def process_item(self, item, spider):
# 这是我们可以根据items类来进行判断
if isinstance(item, Qsbk1Item):
print("这是qsbk1的数据:", item)
elif isinstance(item, Qsbk2Item):
print("这是qsbk2的数据:", item)
elif isinstance(item, Qsbk3Item):
print("这是qsbk3的数据:", item)
else:
print('未知数据')
return item
运行爬虫即可看到效果
其他博文链接
- Python爬虫1.1 — urllib基础用法教程
- Python爬虫1.2 — urllib高级用法教程
- Python爬虫1.3 — requests基础用法教程
- Python爬虫1.4 — requests高级用法教程
- Python爬虫2.1 — BeautifulSoup用法教程
- Python爬虫2.2 — xpath用法教程
- Python爬虫3.1 — json用法教程
- Python爬虫3.2 — csv用法教程
- Python爬虫3.3 — txt用法教程
- Python爬虫4.1 — threading(多线程)用法教程
- Python爬虫4.2 — ajax(动态网页数据抓取)用法教程
- Python爬虫4.3 — selenium基础用法教程
- Python爬虫4.4 — selenium高级用法教程
- Python爬虫4.5 — tesseract(图片验证码识别)用法教程
- Python爬虫5.1 — scrapy框架简单入门
转载:https://blog.csdn.net/Zhihua_W/article/details/103615741