scrapy 保存到 sqlite3


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

運行效果圖:

方式二

使用 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

說明
第二種方式未測試!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM