gpt4 book ai didi

sqlite - 使用管道将数据写入 sqlite 时关闭 sqlite db cur 和 con 的最佳方法

转载 作者:IT王子 更新时间:2023-10-29 06:24:11 24 4
gpt4 key购买 nike

quotes.py 是爬虫文件。

import scrapy    
from project.items import ProjectItem

class QuotesSpider(scrapy.Spider):
name = 'quotes'
allowed_domains = ['quotes.toscrape.com']
start_urls = ['http://quotes.toscrape.com/page/1']

def parse(self, response):
item = ProjectItem()
for quote in response.css('div.quote'):
item['quote'] = quote.css('span.text::text').extract_first()
item['author'] = quote.xpath('span/small/text()').extract_first()
yield item

next_page = response.css('li.next a::attr("href")').extract_first()
if next_page is not None:
yield response.follow(next_page, self.parse)

每页中的作者和引用被提取到项目中。

通过下面的pipelines.py,item['author']和item['quote']可以写入/tmp/test.sqlite

import sqlite3
import json

class ProjectPipeline(object):
def __init__(self):
self.db = r'/tmp/test.sqlite'
self.table = 'data'
self.con = sqlite3.connect(self.db)
self.cur = self.con.cursor()
self.cur.execute("create table {table} (author TEXT,quote TEXT)".format(table=self.table))

def __del__(self):
self.cur.close()
self.con.close()

def process_item(self, item, spider):
self.cur.execute("INSERT INTO {table} VALUES(?,?);".format(table=self.table),(item['author'],item['quote']))
self.con.commit()
return item

运行sipder时有一个小缺点 scrapy crawl quotes在蜘蛛运行期间打开/tmp目录。
我想要一个更好的方法来完成任务。
1.不是在每一项之后都提交?
2.只打开sqlite一次写入所有数据然后关闭它。

最佳答案

就我个人而言,我认为您在完成每个项目后提交的当前方法没有任何问题。提交应该关闭逻辑工作单元(另一方面,回滚应该在出现错误时丢弃它)。在我看来,抓取的项目是独立的,可以被认为是逻辑单元,因此提交是合法的。 (我什至会说需要,因为它可以防止在出现意外错误时丢失数据。)

当然,您也可以按照您的建议进行,最后将所有数据存储一次。但是为此,您必须同时将它们存储在内存中,并且根据项目的大小和数量,它可能是相当多的数据。但是,您可以选择折衷方案并使用已知大小的缓冲区并在缓冲区已满时提交项目。查看修改后的管道类的这个示例:

import sqlite3
import json

class ProjectPipeline(object):
def __init__(self):
self.db = r'/tmp/test.sqlite'
self.table = 'data'
self.buff = list()
self.buff_size = 20
self.con = sqlite3.connect(self.db)
self.cur = self.con.cursor()
self.cur.execute("create table {table} (author TEXT,quote TEXT)".format(table=self.table))

def __del__(self):
if len(self.buff) > 0:
self.cur.executemany("INSERT INTO {table} VALUES(?,?);".format(table=self.table),self.buff)
self.con.commit()
self.cur.close()
self.con.close()

def process_item(self, item, spider):
self.buff.append((item['author'],item['quote']))
if len(self.buff) == self.buff_size:
self.cur.executemany("INSERT INTO {table} VALUES(?,?);".format(table=self.table),self.buff)
self.con.commit()
del self.buff[:]
return item

缓冲区大小设置为 20 个项目,因此每 20 个项目后,它们就会提交到数据库中。最好的办法是将此类设置(连同数据库名称等)存储在 settings.py 中。

关于sqlite - 使用管道将数据写入 sqlite 时关闭 sqlite db cur 和 con 的最佳方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46087013/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com