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 要在爬虫运行之前先创建好。否则会报错,原因不详。

代码


     
     
  1. import sqlite3
  2. class Sqlite3Pipeline(object):
  3. def __init__(self, sqlite_file, sqlite_table):
  4. self.sqlite_file = sqlite_file
  5. self.sqlite_table = sqlite_table
  6. @classmethod
  7. def from_crawler(cls, crawler):
  8. return cls(
  9. sqlite_file = crawler.settings.get('SQLITE_FILE'), # 从 settings.py 提取
  10. sqlite_table = crawler.settings.get('SQLITE_TABLE', 'items')
  11. )
  12. def open_spider(self, spider):
  13. self.conn = sqlite3.connect(self.sqlite_file)
  14. self.cur = self.conn.cursor()
  15. def close_spider(self, spider):
  16. self.conn.close()
  17. def process_item(self, item, spider):
  18. insert_sql = "insert into {0}({1}) values ({2})".format(self.sqlite_table,
  19. ', '.join(item.fields.keys()),
  20. ', '.join(['?'] * len(item.fields.keys())))
  21. self.cur.execute(insert_sql, item.fields.values())
  22. self.conn.commit()
  23. return item

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

2. 文件 settings.py

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


     
     
  1. SQLITE_FILE = 'example.db'
  2. SQLITE_TABLE = 'dmoz'
  3. ITEM_PIPELINES = {
  4. 'myproject.pipelines.Sqlite3Pipeline': 300,
  5. }

3. 运行爬虫

$ scrapy crawl example
     
     

运行效果图:
709432-20160903041422683-19419397.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的例子,基本没变

代码


     
     
  1. from scrapy.exporters import BaseItemExporter
  2. import sqlite3
  3. class Sqlite3ItemExporter(BaseItemExporter):
  4. def __init__(self, file, **kwargs):
  5. self._configure(kwargs)
  6. self.conn = sqlite3.connect(file.name)
  7. self.conn.text_factory = str
  8. self.created_tables = []
  9. def export_item(self, item):
  10. item_class_name = type(item).__name__
  11. if item_class_name not in self.created_tables:
  12. keys = None
  13. if hasattr(item.__class__, 'keys'):
  14. sqlite_keys = item.__class__.sqlite_keys
  15. self._create_table(item_class_name, item.fields.iterkeys(), sqlite_keys)
  16. self.created_tables.append(item_class_name)
  17. field_list = []
  18. value_list = []
  19. for field_name in item.iterkeys():
  20. field_list.append('[%s]' % field_name)
  21. field = item.fields[field_name]
  22. value_list.append(self.serialize_field(field, field_name, item[field_name]))
  23. sql = 'insert or ignore into [%s] (%s) values (%s)' % (item_class_name, ', '.join(field_list), ', '.join(['?' for f in field_list]))
  24. self.conn.execute(sql, value_list)
  25. self.conn.commit()
  26. def _create_table(self, table_name, columns, keys = None):
  27. sql = 'create table if not exists [%s] ' % table_name
  28. column_define = ['[%s] text' % column for column in columns]
  29. print('type: %s' % type(keys))
  30. if keys:
  31. if len(keys) > 0:
  32. primary_key = 'primary key (%s)' % ', '.join(keys[0])
  33. column_define.append(primary_key)
  34. for key in keys[1:]:
  35. column_define.append('unique (%s)' % ', '.join(key))
  36. sql += '(%s)' % ', '.join(column_define)
  37. print('sql: %s' % sql)
  38. self.conn.execute(sql)
  39. self.conn.commit()
  40. def __del__(self):
  41. self.conn.close()

2. 文件 settings.py

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


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

3. 运行爬虫

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

说明
第二种方式未测试!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值