scrapy 保存到 sqlite3

简介: scrapy 爬取到结果后,将结果保存到 sqlite3,有两种方式item PipelineFeed Exporter方式一使用 item Pipeline 有三个步骤文件 pipelines.py 中,编写 Sqlite3Pipeline 类文件 settings.py 中,添加 ITEM_PIPELINES开始运行爬虫: scrapy crawl example1. 文件 pipelines.py说明:参考了官网文档的 MongoDB 的例子要求:表格 SQLITE_TABLE 要在爬虫运行之前先创建好。

scrapy 爬取到结果后,将结果保存到 sqlite3,有两种方式

  • item Pipeline
  • Feed Exporter

方式一

使用 item Pipeline 有三个步骤

  1. 文件 pipelines.py 中,编写 Sqlite3Pipeline
  2. 文件 settings.py 中,添加 ITEM_PIPELINES
  3. 开始运行爬虫: scrapy crawl example

1. 文件 pipelines.py

说明
参考了官网文档的 MongoDB 的例子

要求
表格 SQLITE_TABLE 要在爬虫运行之前先创建好。否则会报错,原因不详。

代码

import sqlite3


class Sqlite3Pipeline(object):

    def __init__(self, sqlite_file, sqlite_table):
        self.sqlite_file = sqlite_file
        self.sqlite_table = sqlite_table
        
    @classmethod
    def from_crawler(cls, crawler):
        return cls(
            sqlite_file = crawler.settings.get('SQLITE_FILE'), # 从 settings.py 提取
            sqlite_table = crawler.settings.get('SQLITE_TABLE', 'items')
        )

    def open_spider(self, spider):
        self.conn = sqlite3.connect(self.sqlite_file)
        self.cur = self.conn.cursor()

    def close_spider(self, spider):
        self.conn.close()

    def process_item(self, item, spider):
        insert_sql = "insert into {0}({1}) values ({2})".format(self.sqlite_table, 
                                                                ', '.join(item.fields.keys()),
                                                                ', '.join(['?'] * len(item.fields.keys())))
        self.cur.execute(insert_sql, item.fields.values())
        self.conn.commit()
        
        return item

补充:
Github 有一个使用 twisted 操作 sqlite3 的例子,见这里。请自行对比。

2. 文件 settings.py

激活前面的 Sqlite3Pipeline 类,需要
添加

SQLITE_FILE = 'example.db'
SQLITE_TABLE = 'dmoz'

ITEM_PIPELINES = {
    'myproject.pipelines.Sqlite3Pipeline': 300,
}

3. 运行爬虫

$ scrapy crawl example

运行效果图:
img_6b4256040a5d3e28b84e26f5bcb70f6c.png

方式二

使用 Feed Exporter 有三个步骤

  1. 文件 exporters.py 中,编写 Sqlite3ItemExporter
  2. 文件 settings.py 中,添加 FEED_EXPORTERS
  3. 开始运行爬虫: scrapy crawl example -o example.db -t sqlite3

1. 文件 exporters.py

说明
参考了Github的例子,基本没变

代码

from scrapy.exporters import BaseItemExporter
import sqlite3

class Sqlite3ItemExporter(BaseItemExporter):
    
    def __init__(self, file, **kwargs):
        self._configure(kwargs)
        self.conn = sqlite3.connect(file.name)
        self.conn.text_factory = str
        self.created_tables = []
    
    def export_item(self, item):        
        item_class_name = type(item).__name__
        
        if item_class_name not in self.created_tables:
            keys = None
            if hasattr(item.__class__, 'keys'):
                sqlite_keys = item.__class__.sqlite_keys
            self._create_table(item_class_name, item.fields.iterkeys(), sqlite_keys)
            self.created_tables.append(item_class_name)
        
        field_list = []
        value_list = []
        for field_name in item.iterkeys():
            field_list.append('[%s]' % field_name)
            field = item.fields[field_name]
            value_list.append(self.serialize_field(field, field_name, item[field_name]))
        
        sql = 'insert or ignore into [%s] (%s) values (%s)' % (item_class_name, ', '.join(field_list), ', '.join(['?' for f in field_list]))
        self.conn.execute(sql, value_list)
        self.conn.commit()
            
    def _create_table(self, table_name, columns, keys = None):
        sql = 'create table if not exists [%s] ' % table_name
        
        column_define = ['[%s] text' % column for column in columns]
        print('type: %s' % type(keys))
        if keys:
            if len(keys) > 0:
                primary_key = 'primary key (%s)' % ', '.join(keys[0])
                column_define.append(primary_key)
                
            for key in keys[1:]:
                column_define.append('unique (%s)' % ', '.join(key))
        
        sql += '(%s)' % ', '.join(column_define)
        
        print('sql: %s' % sql)
        self.conn.execute(sql)
        self.conn.commit()
        
    def __del__(self):
        self.conn.close()

2. 文件 settings.py

激活前面的 Sqlite3ItemExporter 类,需要
添加


FEED_EXPORTERS = {
    'sqlite3': 'myproject.exporters.Sqlite3ItemExporter',
}

3. 运行爬虫

$ scrapy crawl example -o example.db -t sqlite3

说明
第二种方式未测试!

目录
相关文章
|
数据采集 监控 数据可视化
Scrapy可视化管理管理工具总结
Scrapy可视化管理管理工具总结
1503 0
Scrapy可视化管理管理工具总结
|
Web App开发 对象存储
解决:x509: cannot validate certificate for IP 报错
问题 今天调用上传接口上传文件时,遇到了一个 x509 类型报错,具体报错信息如下: 2021-10-15 17:46:13.145 ERROR oss/upload.go:210 upload process Failed {"error": "Post "https://192.168.215.139:9443/store/file/upload\": x509: cannot validate certificate for 192.168.215.139 because it doesn't contain any IP SANs"} panic: send on closed cha
1720 0
|
10月前
|
机器学习/深度学习 人工智能 自然语言处理
探索人工智能的无限可能:技术前沿与应用实践
【10月更文挑战第23天】探索人工智能的无限可能:技术前沿与应用实践
|
数据处理 开发者 数据格式
Nest.js 实战 (四):利用 Pipe 管道实现数据验证和转换
这篇文章介绍了Nest.js框架中管道的概念和使用。管道是一种强大的功能,用于在请求数据到达控制器方法之前对其进行预处理,如转换、验证、清理等。文章详细解释了数据转换、数据验证、错误处理和一致性等管道的主要用途,并通过代码示例演示了如何使用内置管道和自定义管道。最后,文章总结了管道在提升应用健壮性和安全性方面的作用,认为合理利用管道可以加速开发周期,提高软件质量。
248 0
|
数据采集 Java Python
Python并发编程:多线程(threading模块)
本文详细介绍了Python的threading模块,包括线程的创建、线程同步、线程池的使用,并通过多个示例展示了如何在实际项目中应用这些技术。通过学习这些内容,您应该能够熟练掌握Python中的多线程编程,提高编写并发程序的能力。 多线程编程可以显著提高程序的并发性能,但也带来了新的挑战和问题。在使用多线程时,需要注意避免死锁、限制共享资源的访问,并尽量使用线程池来管理和控制线程。
visual studio code 在雷电模拟器上链接Autojs
visual studio code 在雷电模拟器上链接Autojs
387 0
|
SQL JSON Java
Flink报错问题之执行sqlQuery报错如何解决
Apache Flink是由Apache软件基金会开发的开源流处理框架,其核心是用Java和Scala编写的分布式流数据流引擎。本合集提供有关Apache Flink相关技术、使用技巧和最佳实践的资源。
|
机器学习/深度学习 自然语言处理 数据可视化
nlp入门之spaCy工具的使用
本文作为nlp开山篇的第四篇,简要介绍了spaCy工具的用法
|
数据采集 数据可视化 应用服务中间件
Python爬虫:scrapy从项目创建到部署可视化定时任务运行
Python爬虫:scrapy从项目创建到部署可视化定时任务运行
946 0
Python爬虫:scrapy从项目创建到部署可视化定时任务运行