爬虫Scrapy笔记(三)、pipelines

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,
}

接下里就等着正主登场了。下一章节,我们来看下如何驱动一只爬虫。

发表评论

邮箱地址不会被公开。 必填项已用*标注