Welcome To Jeremy's Blog --------------------------            JeremyYu

3.4 scrapy框架 -- Item Pipeline


1.Item Pipeline 介绍

1 ItemPipeline是scrapy框架用于持久化存储的核心组件,该组件的作用就是将爬取到的数据清洗后进行持久化存储.实际上我们一般将ItemPipeline分为细分为两部分,一部分为Item,即定义数据存储的数据结构,一般用于解析方法中,实例化item对象,将目标数据存储在item的属性中;另一部分为Pipeline,即进行数据的存储或进一步清洗,该部分出现在item对象出现后,操作也基本上是针对item的.
2 所以,总结来说ItemPipeline分为两部分:
3   (1).item:定义数据存储的结构
4   (2).Pipeline:定义数据存进数据库或爬取数据的进一步清洗

 

返回顶部


2.item使用

item在项目中应定义在items.py文件中

1 # 简单示例: 加入爬取的数据为新闻的: 标题, 发布时间, 发布人, 评论数等信息, 可以定义如下的item
2 
3 import scrapy
4 
5 classNewsPipeline(scrapy.Item):
6     news_title = scrapy.Field()# 新闻标题信息
7     news_time = scrapy.Field()# 新闻发布时间信息
8     news_auth = scrapy.Field()# 新闻发布人信息
9     news_comment = scrapy.Field()# 新闻评论数信息

 

返回顶部


3.pipeline 介绍

1 1.Pipeline功能:数据进一步清洗及数据的持久化存储
2 
3 2.Pipeline可实现方法:
4     1).Pipeline管道类必须实现一个方法,即process_item(item, spider)方法
5     2).Pipelien其他方法:
6             open_spider(spider)
7             close_spider(spider)
8             from _crawler(cls, crawler)    

 

返回顶部


4.Pipeline管道类的方法详解

1 # process_item(item, spider)方法:
2 1.该方法是必须实现的方法,该方法用于将数据存储在数据库中,该方法必须返回一个item或抛出一个DropItem异常,返回item对象是为了下一个管道类能够接受到item对象进行其他对item的处理操作
3 
4 2.process_item方法的参数:
5     1).item参数:是item对象,即管道类中要被处理的item对象, item对象中存储着目标数据
6     2).spider参数: spider是产生item对象的spider爬虫程序
7 
8 3.process_item返回值:
9   1).item对象:爬取的数据往往要存储在多个数据库中,该方法返回item对象可以被下一个优先级低的管道类中的process_item方法接收到

 

返回顶部

1 # open_spider(self, spider)方法:
2   1.open_spider()方法是在Spider开启的是后被自动调用的,可以在该方法方法中做一些初始化的操作,如数据库的连接操作.
3 
4   2.open_spider的参数为self, spider,固定的.

 

1 # close_spider(self, spider)方法:
2   1.close_spider()方法是在spider关闭的时候自动调用的,该方法中可以实现一些收尾的工作,如关闭数据库连接
3   2.spider和self参数是固定的, spider是被关闭的对象

 

1 # from_crawler(cls, crawler)方法:
2   1.该方法是一个类方法,应该用@classmethod进行装饰.
3   2.该方法的作用是通过crawler对象,可以获取scrapy的所有核心组件,如全局的配置信息

 

1 # 在管道类中各方法执行顺序:(大致是这样的, 有助于理解后续管道类连接数据库持久化存储)
2       1.from_crawler()
3       2.__init__()
4       3.open_spider()
5       4.process_item()
6       5.close_spider()

 

返回顶部


5.Pipeline相关配置信息

在settings文件中有关于Pipeline的配置信息:

1 ITEM_PIPELINES ={
2 'qsbk.pipelines.QsbkPipeline':300,# qsbk项目中的pipelines, 对应QsbkPipeline管道类, 优先级为300
3 }
4 
5 说明:
6     1.自定义的管道类需要在settings文件中注册,键为管道类名,值为对应的管道类的优先级
7     2.优先级数字越小,越先执行

 

返回顶部


6.Python操作三大主流数据库接口

 1 # Python操作MySQL
 2 import pymysql
 3 classMysqlPipeline(object):
 4     def __init__(self, host, database, user, password, port):
 5     self.host = host
 6     self.database = database
 7     self.user = user
 8     self.password = password
 9     self.port = port
10 
11   @classmethod
12   def from_crawler(cls, crawler):
13     return cls(
14       host = crawler.settings.get('MYSQL_HOST'),
15       database = crawler.settings.get('MYSQL_DATABASE'),
16       user = crawler.settings.get('MYSQL_USER'),
17       password = crawler.settings.get('MYSQL_PASSWORD'),
18       port = crawler.settings.get('MYSQL_PORT')
19     )
20 
21   def open_spider(self, spider):
22     self.db = pymysql.connect(self.host,self.user,self.password,self.database, charset='utf8', port=self.port)
23     self.cursor =self.db.cursor()
24 
25   def process_item(self, item, spider):
26     data = dict(item)
27     keys =','.join(data.keys())
28     values =','.join(['%s']*len(data))
29     sql ='insert into %s(%s) values (s%)'%(item.table, keys, values)
30     self.cursor.execute(sql, tuple(data.values()))
31     self.db.commit()
32     return item

 

返回顶部

 1 # Python操作MongoDB
 2 import pymongo
 3 
 4 classMongoPipeline(object):
 5 
 6   def __init__(self, mongo_uri, mongo_db):
 7     self.mongo_uri = mongo_uri
 8     self.mongo_db = mongo_db
 9 
10   @classmethod
11   def from_crawler(cls, crawler):
12     return cls(
13       mongo_uri = crawler.settings.get('MONGO_URI'),
14       mongo_db = crawler.settings.get('MONGO_DB')
15     )
16 
17   def open_spider(self, spider):
18     self.client = pymongo.MongoClient(self.mongo_uri)
19     self.db =self.Client[self.mongo_db]
20
21   def process_item(self, item, spider): 22     self.db[item.collection].insert(dict(item)) 23     return item 24 25   def close_spider(self, spider): 26     self.client.close()

 

返回顶部

 1 # Python操作Redis
 2 
 3 from redis importStrictRedis
 4 
 5 classRedisPipeline(object):
 6 
 7   def __init__(self, redis_uri, redis_port , redis_db, redis_password):
 8     self.redis_uri = redis_uri
 9     self.redis_port = redis_port
10     self.redis_db = redis_db
11     self.reids_password = redis_password
12 
13   @classmethod
14   def from_crawler(cls, crawler):
15     return cls(
16       redis_uri = crawler.settings.get('REDIS_URI'),
17       redis_port = crawler.settings.get('REDIS_USER'),
18       redis_db = crawler.settings.get('REDIS_DB'),
19       reids_password = crawler.settings.get('REDIS_PASSWORD')
20     )
21 
22   def open_spider(self, spider):
23     redis =StrictRedis(host=self.reidis_uri, port=self.redis_port, db=self.redis_db, password=self.redis_password)
24 
25   def process_item(item, spider):
26     redis.mset(dict(item))
27     return item

 

返回顶部


7.Image Pipeline —- 大文件下载

 1 1.在scrapy框架中有专门针对大文件下载的管道类---ImagePipeline.该类继承ImagesPipeline类,需要自己实现三个方法: get_media_reqiests(), file_path(), item_completed()
 2 
 3 2.三个方法:
 4     1).get_media_requests():用于生成Request对象,引擎将Request加入到调度队列中,等待被调度执行下载.
 5     2).file_path():定义下载的文件的保存文件名.
 6     3).item_completed():当单个Item完成下载时的处理方法.下载成功返回item,下载失败抛出异常,则该item将被忽略.
 7 
 8 3.settings配置文件中的配置项:
 9 IMAGES_STORE ='./images'
10 ITEM_PIPELINE ={
11 'images360.pipelines.ImagePipeline':300,
12 'images360.pipelines.MongoPipeline':301,
13 'images360.pipelines.MysqlPipeline'302
14 }

 

返回顶部


8.Image Pipeline简单示例

 1 from scrapy importRequest
 2 from scrapy.exception importDropItem
 3 from scrapy.pipeline.images importImagePipeline
 4 
 5 classImagePipeline(ImagesPipeline):
 6 
 7   def file_path(self, request, response=None, info=None):
 8     url = request.url
 9     file_name = url.split("/")[-1]
10     return file_name
11 
12   def item_completed(self, results, item, info):
13     image_paths =[x['path']for ok, x in results if ok]
14     if not image_paths:
15     raist DropItem('图片下载失败')
16     return item
17 
18   def get_media_requests(self, item, info):
19     yieldRequest(item['url'])

 

返回顶部

posted on 2018-03-18 06:41  Jeremy_Yu  阅读(168)  评论(0)    收藏  举报

导航