使用pipeline
从pipeline的字典形可以看出来,pipeline可以有多个,⽽且确实pipeline能够定义多个
为什么需要多个pipeline:
-
可能会有多个spider,不同的pipeline处理不同的item的内容
-
⼀个spider的内容可以要做不同的操作,⽐如存⼊不同的数据库中
注意:
- pipeline的权重越⼩优先级越⾼
- pipeline中process_item⽅法名不能修改为其他的名称
首先,我们需要在settings.py文件中找到如下部分的代码,并取消注释
可以有多个MyspiderPipeline类,但是,每增加一个类,都需要在settings.py文件中做出相应的配置
说明:后面的数字(300)代表的就是权重,并且数字不能相同
验证pipeline是否能用
我们在代码中需要有生成器
在Scrapy爬虫中,yield关键字用于产生一个生成器(generator)。当你在一个函数中使用yield而不是return时,这个函数就变成了一个生成器。每次调用生成器的next()方法(或使用for循环迭代)时,它会执行到下一个yield语句并返回yield后面表达式的值,同时保存当前执行上下文的状态。当下次再次调用时,它会从上次离开的地方继续执行,直到遇到下一个yield或函数结束。
每当解析到一个新闻标题时,就会创建一个包含该标题的字典item,然后通过yield item将其发送出去。这样,Scrapy就可以接收到每一个新闻标题,并根据配置的管道来处理这些标题,比如将它们保存到数据库或文件中。
在pipelines.py文件中输入一条打印语句
运行爬虫程序,我们可以获取到数据
保存为json文件
class MyspiderPipeline:
def __init__(self):
self.f = open('demo.json', 'w', encoding='UTF-8')
def open_spider(self, spider):
print("爬虫开始了")
def process_item(self, item, spider):
print(item)
print("文件写入中...")
item_json = json.dumps(item, ensure_ascii=False)
self.f.write(item_json + "\n")
return item
def close_spider(self, spider):
print("爬虫结束了")
self.f.close()
多管道
在我们使用Scrapy时可能会有多个spider,不同的pipeline处理不同的item的内容,那么如何区分item是来自哪个管道呢
关于spider参数:
我们打印spider参数就可以看到是属于哪个管道的
我们可以通过spider.name即可获取管道名字,这样使用判断语句即可区分开来
PS E:\Study\code\Python\网络爬虫\ScrapyStudy\mySpider> scrapy genspider jd jd.com
Created spider 'jd' using template 'basic' in module:
mySpider.spiders.jd
PS E:\Study\code\Python\网络爬虫\ScrapyStudy\mySpider>
我们创建一个关于jd的爬虫,注意:需要修改一下start_urls
方法1:
def process_item(self, item, spider):
# 方法1
if spider.name == 'xl':
print(spider.name)
# print(item)
# print("文件写入中...")
item_json = json.dumps(item, ensure_ascii=False)
self.f.write(item_json + "\n")
return item
方法2:
在item的字典中添加一个come_from字段,用来判断
def parse(self, response):
# print("=" * 30)
# print(response)
# print(type(response))
# print("=" * 30)
li_list = response.xpath("//div[@class='main-nav']//ul/li/a/text()")
# print("获取到:{}个标题".format(len(li_list)))
# print(type(li_list))
item = {}
for li in li_list:
item['title'] = li.extract()
# print(item)
item['come_from'] = 'xl'
yield item # 生成器
# 方法2
print(item['come_from'])
if item['come_from'] == 'xl':
return item