用Pipeline的目的
1.清理数据。
2.验证数据的有效性。
3.查重并丢弃。
4.将数据按照自定义的格式存储到文件中。
5.将数据保存到数据库中。
6.欢迎补充
本文基于系列七代码的基础上修改
1.编写Pipeline
在pipelines.py文件编写Pipeline的逻辑
我这里写了三个Pipeline一个是QidianHotPipeline把类型转换为简写,一个是DuplicatesPipeline去除作者姓名重复的项目,还有一个是SaveToTxtPipeline将数据保存于文本文档当中
注:
Pipline中,除了必须实现的process_item()方法外还有3个常用的方法—open_spider(),close_spider(),from_crawler()
open_spider(self,spider)方法:Spider开启时(爬取数据前)执行该方法,参数spider为被开启的spider,该方法通常同于在数据处理前完成一些初始化工作,如打开文件和连接数据库。
close_spider(self,spider)方法:Spider关闭时(所有爬取数据完毕)执行该方法,参数spider为被关闭的spider,该方法通常同于在数据处理完成后,完成一些清理工作,如关闭文件和关闭数据库。
from_crawler(cls,crawler)方法:该方法被调用时,会创建一个新的Item Pipeline对象,参数crawler为使用当前管道的项目。该方法通常用于提供对Scrapy核心组件的访问,如访问settings.py文件
2.启用Pipeline
在settings.py文件配置启用哪个Pipeline并指定执行次序
指定的数字越小,优先级越高
settings.py文件配置太简单这里不把的完整代码放上来了
pipelines.py完整代码
from scrapy.exceptions import DropItem
#简写转换
class QidianHotPipeline(object):
def process_item(self, item, spider):
#判断小说形式是连载还是完结,并替换简称
if item["type"] == "都市":
item["type"] = "DS"
elif item["type"] == "玄幻":
item["type"] = "XH"
elif item["type"] == "悬疑":
item["type"] = "XY"
else:
item["type"] = "QT"
return item
#去除作者姓名重复的项目
class DuplicatesPipeline(object):
def __init__(self):
#定义一个保存作者姓名的集合
self.author_set = set()
def process_item(self, item, spider):
if item["author"] in self.author_set:
#抛弃重复的Item项
#raise
raise DropItem("查找到重复姓名的项目:%s"%item)
else:self.author_set.add(item['author'])
return item
#将数据保存于文本文档当中
class SaveToTxtPipeline(object):
#文件名称
#file_name = "hot.txt"
#文件对象
file = None
@classmethod
def from_crawler(cls,crawler):
#获取配置文件中的FILE_NAME的值
#如果FILE_NAME的值获取失败,就使用默认值hot2.txt
cls.file_name = crawler.settings.get("FILE_NAME","hot2.txt")
return cls()
#Spider开启时,执行打开文件操作
def open_spider(self,spider):
#以追加形式打开文件,a:以追加方式打开
self.file = open(self.file_name, "a", encoding="utf-8")
#数据处理
def process_item(self, item, spider):
#获取item中的各个字段,将其连接成一个字符串
#字段直接用分号分开
#字符串末尾要有换行符\n
novel_str = item['name'] + ";" + item['author'] + ";" + item['type'] + ";" + item['form'] + "\n"
self.file.write(novel_str)
return item
#关闭Spider时,执行关闭文件操作
def close_spider(self,spider):
self.file.close()