pipelines 主要是用于接收一个 item,然后处理这个 item,通过 pipeline 来决定是否需要继续处理还是存储起来,亦或是丢弃等等。
他也很简单,只要实现一个接口方法就可以
def process_item(self, item, spider):
下面我们来实现这个方法,在之前我们需要做一些预处理,我们想把这些信心存储起来,简单起见,我们就把 item 存储在 sqlite 中。sqlite 是一个简单的数据库,不做过多介绍。
我们需要把爬虫的启动和关闭和数据库的启动和关闭关联起来,防止出现异常。
scrapy 中本身包含如下信号
#signals.py
engine_started = object()
engine_stopped = object()
spider_opened = object()
spider_idle = object()
spider_closed = object()
spider_error = object()
request_scheduled = object()
request_dropped = object()
response_received = object()
response_downloaded = object()
item_scraped = object()
item_dropped = object()
# for backwards compatibility
stats_spider_opened = spider_opened
stats_spider_closing = spider_closed
stats_spider_closed = spider_closed
item_passed = item_scraped
request_received = request_scheduled
这里使用了 dispatcher.connect 函数
class SamplePipeline(object):
#文件名
filename = 'oschina.sqlite'
def __init__(self):
self.conn = None
# 添加信号分发器,控制数据库的连接与关闭
dispatcher.connect(self.started, signals.engine_started)
dispatcher.connect(self.stopped, signals.engine_stopped)
# 初始换
def started(self):
# 如果路径存在,表示数据库已创建,连接数据库
if path.exists(self.filename):
self.conn = sqlite3.connect(self.filename)
self.conn.text_factory = str
# 否则表示数据库不存在,创建数据库,并创建相关表
else:
self.conn = self.init_table(self.filename)
# 清理相关工作,提交事务,关闭连接
def stopped(self):
if self.conn is not None:
self.conn.commit()
self.conn.close()
self.conn = None
# 建表
def init_table(self, filename):
conn = sqlite3.connect(filename)
# 这里的表结构和item相对应
conn.execute("""create table oschina(
id integer primary key autoincrement,
title text,
author text,
collect int,
comment int
)""")
conn.commit()
return conn
def process_item(self, item, spider):
self.conn.execute(
'insert or replace into oschina values((select id from oschina a where a.title=?),?,?,?,?)',
(item['title'][0], item['title'][0], item['author'][0], int(item['collect'][0]),
int(item['comment'][0])))
return item
这样,我们就完成了简单的数据持久化操作。注意一点的是,需要在setting.py中开启pipeline设置。
ITEM_PIPELINES = {
当有多个Pipeline,可加在后面,后面数据表示执行顺序
'sample.pipelines.SamplePipeline': 300,
}
接下里就等着正主登场了。下一章节,我们来看下如何驱动一只爬虫。