scrapy 中的异步方法query = self.dbpool.runInteraction(self.do_insert, item)参数item不能传递?

image.png

在scrapy 管道文件中使用了adbapi这个包
现在导致query = self.dbpool.runInteraction(self.do_insert, item)中的item,不能传递到do_insert方法中,导致不能入库,在do_insert中怎么拿到item值
请教一下大佬有遇到过吗?
谢谢

阅读 878
avatarAI BotBETA

看起来你正在使用Scrapy框架进行网络爬虫的开发,并且你在处理异步数据库操作时遇到了问题。

在Scrapy的pipelines.py文件中,如果你使用了adbapi这个包并且试图把item传递给runInteraction方法,可能会出现问题。这是因为runInteraction方法本身是异步的,而item参数通常是在同步的上下文中使用的。

在这种情况下,你需要确保你的数据库操作是异步的。Scrapy的adbapi包提供了一个run_in_thread装饰器,你可以使用它来确保数据库操作是异步执行的。

以下是一个示例,展示了如何在Scrapy的管道中使用异步数据库操作:

import sqlite3
from scrapy.exceptions import DropItem
from scrapy.pipelines.db import DBPipeline
from scrapy.utils.project import get_project_settings

class MyDBPipeline(DBPipeline):

    def __init__(self, host, user, password, db, table, **kwargs):
        super().__init__(**kwargs)
        self.conn = sqlite3.connect(f"file:{table}?mode=memory&cache=shared")
        self.cursor = self.conn.cursor()

    @classmethod
    def from_crawler(cls, crawler):
        return cls(
            host=get_project_settings().get('DB_HOST'),
            user=get_project_settings().get('DB_USER'),
            password=get_project_settings().get('DB_PASSWORD'),
            db=get_project_settings().get('DB_NAME'),
            table=get_project_settings().get('DB_TABLE'),
            settings=crawler.settings
        )

    def process_item(self, item, spider):
        query = self.cursor.mogrify("INSERT INTO %s VALUES (%s)" % 
            (self.table, ','.join(['?']*(len(item)-1))), item)
        self.cursor.execute(query, item)
        self.conn.commit()
        return item

在上述代码中,process_item方法负责处理每一个从爬虫抓取的项(item)。这个方法首先构建了一个SQL插入语句,然后执行这个语句,把项的内容插入到数据库中。在这个过程中,项的内容被作为元组传递给execute方法,这个元组的内容会被插入到SQL语句的占位符中(即问号)。这就确保了项的内容能被正确地插入到数据库中,而不需要把项作为参数传递给其他方法。

注意:代码中的from_crawler方法用于从爬虫中创建一个管道类的实例。你可以在你的settings.py文件中设置数据库的连接参数。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题