Scrapy深入理解pipelines文件
每个管道组件都是具有某个功能的Python类,常见的功能有:清理html数据,做确认,去重,存入数据。每个管道的类必须有以下方法:
- process_item(self,item,spider)
- open_spider(self,spider)
- close_spider(self,spider)
- from_crawler(cls,crawler)
class MyspiderPipeline(object):
def open_spider(self,spider):#在爬虫开启的时候执行,仅执行一次
spider.hello='Hello World!'
然后我们就可以在爬虫文件中获取变量值import scrapy
class MYSpider(scrapy.Spider):
...
def parse(self, response):
print(self.hello+'*'*100)
然后运行我们的爬虫,那么会显示:
Hello World!****************************************************************************************************
既然是爬虫开始的时候仅会运行一次,那么可以用来定义一些固定的信息,比方说连接数据库,连接数据库我们通常也是只进行一次。我们可以修改pipelines文件:
from pymongo import MongoClient
class MyspiderPipeline(object):
def open_spider(self,spider):#在爬虫开启的时候执行,仅执行一次
client=MongoClient()#实例化连接
self.collection=client['table']['test']#通过实例创建数据库和表
def process_item(self, item, spider):
item=...
self.collection.insert(dict(item))#插入数据
return item
我们通常要把爬取到的数据保存为文件,比方说json,csv文件,那么我们需要在爬虫开启的时候打开文件爬虫结束的时候关闭文件,文件在爬虫开始的时候打开,在爬虫结束的时候关闭,正好可以使用open_spider和close_spider,具体可以参考代码:
import json
class MyspiderPipeline(object):
def open_spider(self,spider):#在爬虫开启的时候执行,仅执行一次
self.file=open(spider.settings.get('SAVE_FILE','./test.json'),'w')
def close_spider(self,spider):#在爬虫关闭的时候执行,仅执行一次
self.file.close()
def process_item(self, item, spider):
line=json.dumps(dict(item))+"\n"
self.file.write(line)
return item #不return的情况下,另一个权重较低的pipeline就不会获取到item
这样就可以保存json文件到本地了,那么如果爬虫爬到一半出错了,数据就不会保存到本地了。这是因为文件写入操作,需要关闭文件,数据才会写入,爬虫出错意味着爬虫没有关闭,也就是文件没有关闭,所以数据的写入可能会丢失。当然你可以使用with open,我也没试过。一般都是把数据保存在数据库中去的,爬虫报错也不会影响数据的丢失。
如何处理多个scrapy爬虫,多个pipeline
通常我们的scrapy爬虫项目是需要有很多个爬虫的,仅仅存在一个爬虫,是不能狗称之为爬虫项目的。当然了,我们在settings配置文件中开启管道的时候就会发现,pipeline是一个字典形式,就是说pipeline可以有多个,而且确实pipeline能够定义多个,那么我们需要知道为什么会有多个pipeline:
- 1.存在多个spider,不同的pipeline处理不同的item内容
- 2.一个spider的内容可能要做不同的操作,比方说存入不同的数据库中去
pipeline的权重越小优先级也越高,其中pipeline中的process_item是不可以修改为其他的名字的scrapy的pipelines.py
import json#存储为json数据吧
class MyspiderPipeline(object):
def process_item(self, item, spider): #item是爬虫文件yield出来的数据,实现存储
with open('filename.txt','a') as f:
json.dump(item,f,ensure_ascii=False,indent=2)
完成pipeline代码之后需要在settings文件开启管道
scrapy的settings.py# Configure item pipelines
# See https://doc.scrapy.org/en/latest/topics/item-pipeline.html
ITEM_PIPELINES = {
'myspider.pipelines.ErshoufangPipeline': 300,
#pipeline的位置 权重
#如果存在多个pipeline的话,添加就可以了
}
那么我们按照固定的代码来创建一个scrapy爬虫文件:
scrapy startproject myspider #创建一个myspider爬虫
cd myspider #进入myspider文件
scrapy genspider ershou second.zz.fccs.com
scrapy genspider e1yu e1yu.com
scrapy genspider meizi www.lmmpic.com
通常一个爬虫项目是需要爬多个网站的,所以我们创建了三个爬虫文件,这三个爬虫文件全部在spiders文件夹下,如果在命令行创建网址需要加引号,网址前面也不要加http。那么爬虫的数据会先到pipeline中,网站的数据不一样,我们处理的方式也就不一样吗,所以就需要多个pipeline来处理,我们可以在pipelines.py文件中进行判断:
class MyspiderPipeline(object):
def process_item(self, item, spider):
if ...:
...
else ...:
...
else ...:
...
return item
这只是一个格式,具体的判断内容,需要我们在每一个爬虫中自定义一个字段,比方说刚才建的ershoufang爬虫,我们可以在ershoufang爬虫文件这样写:
import scrapy
class ErshoufangSpider(scrapy.Spider):
name = 'ershoufang'
allowed_domains = ['http://second.zz.fccs.com/']
start_urls = ['http://http://second.zz.fccs.com//']
def parse(self, response):
item={}
item['come_from']='ershoufang'
pass
之后我们就可以在pipelines文件中进行判断,对于不同的爬虫,有不同的解析方式。我们可以注意到pipelines中MyspiderPipeline这个类,接收两个参数item和spider,这个spider就是我们的爬虫,那么也可以根据spider的name属性来判断:
class MyspiderPipeline(object):
def process_item(self, item, spider):
if spider.name=='ershoufang':
...
return item
class MyspiderPipeline1(object):
def process_item(self, item, spider):
if spider.name == 'e1yu':
...
return item
class MyspiderPipeline2(object):
def process_item(self, item, spider):
#if item['come_from'] == 'meizi':
if spider.name == 'meizi':
...
return item
2. 本站不保证所提供下载的资源的准确性、安全性和完整性,资源仅供下载学习之用!如有链接无法下载、失效或广告,请联系客服处理!
3. 您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容资源!如用于商业或者非法用途,与本站无关,一切后果请用户自负!