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'])
浙公网安备 33010602011771号