python - 非阻塞 Scrapy 管道到数据库

标签 python sqlalchemy scrapy twisted nonblocking

我在 Scrapy 中有一个获取数据项的网络抓取工具。我也想将它们异步插入到数据库中。

例如,我有一个使用 SQLAlchemy Core 将一些项目插入我的数据库的事务:

def process_item(self, item, spider):
    with self.connection.begin() as conn:
        conn.execute(insert(table1).values(item['part1'])
        conn.execute(insert(table2).values(item['part2'])

我知道可以通过 alchimia 将 SQLAlchemy Core 与 Twisted 异步使用. alchimia 的文档代码示例如下。

我不明白的是如何在 alchimia 框架中使用我上面的代码。如何设置 process_item 以使用 react 器?

我可以做这样的事情吗?

@inlineCallbacks
def process_item(self, item, spider):
    with self.connection.begin() as conn:
        yield conn.execute(insert(table1).values(item['part1'])
        yield conn.execute(insert(table2).values(item['part2'])

reactor 部分怎么写?

或者是否有更简单的方法在 Scrapy 管道中进行非阻塞数据库插入?


作为引用,这里是 alchimia 文档中的代码示例:

from alchimia import TWISTED_STRATEGY

from sqlalchemy import (
    create_engine, MetaData, Table, Column, Integer, String
)
from sqlalchemy.schema import CreateTable

from twisted.internet.defer import inlineCallbacks
from twisted.internet.task import react


@inlineCallbacks
def main(reactor):
    engine = create_engine(
        "sqlite://", reactor=reactor, strategy=TWISTED_STRATEGY
    )

    metadata = MetaData()
    users = Table("users", metadata,
        Column("id", Integer(), primary_key=True),
        Column("name", String()),
    )

    # Create the table
    yield engine.execute(CreateTable(users))

    # Insert some users
    yield engine.execute(users.insert().values(name="Jeremy Goodwin"))
    yield engine.execute(users.insert().values(name="Natalie Hurley"))
    yield engine.execute(users.insert().values(name="Dan Rydell"))
    yield engine.execute(users.insert().values(name="Casey McCall"))
    yield engine.execute(users.insert().values(name="Dana Whitaker"))

    result = yield engine.execute(users.select(users.c.name.startswith("D")))
    d_users = yield result.fetchall()
    # Print out the users
    for user in d_users:
        print "Username: %s" % user[users.c.name]

if __name__ == "__main__":
    react(main, [])

最佳答案

How can I set up process_item to use a reactor?

您无需管理管道中的另一个 react 器。
相反,您可以通过从管道返回延迟来在项目管道内进行异步数据库交互。

另见 Scrapy's docsample code doing asynchronous operations within an item pipeline by returning a deferred .

关于python - 非阻塞 Scrapy 管道到数据库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42631186/

相关文章:

python - 在以下输入字段上使用 Scrapy 和 send_keys

python - 正则表达式提取消息

python - numba @vectorize 目标 ='parallel' TypeError

python - 我可以防止修改 Python 中的对象吗?

python - 通过 SQL Alchemy 中的表插入多对多关联

python - 如何使用 SQLalchemy 获取列表中提供的键的所有行?

python - 如何从 SQLAlchemy 模型中确定子对象的类型?

python - Scrapy的爬虫中间件和下载器中间件有什么区别?

python阻塞套接字,发送立即返回

csv - Python Scrapy : How to get CSVItemExporter to write columns in a specific order