python - 在Scrapy中使用Sqlalchemy更新表行

标签 python sqlalchemy scrapy

我正在使用 scrapy 和 sqlalchemy。在我的 Spider 中,我从表中进行选择并使用以下命令创建请求:

def start_requests(self):

    db_path = "sqlite:///"+settings.SETTINGS_PATH+"\\data.db"
    source_table= self.table

    engine = create_engine(db_path)
    Base = declarative_base()
    # metadata = Base.metadata
    # Look up the existing tables from database
    Base.metadata.reflect(engine)

    # Create class that maps via ORM to the database table
    table = type(source_table, (Base,), {'__tablename__': source_table})

    Session = sessionmaker(bind=engine)
    session = Session()
    i = 0

for row in session.query(table).filter(table.url.contains('http')).limit(3):

    i += 1
    print(row.url)
    yield Request(url=row.url, headers= headers, callback=self.get_PDF,meta={'session': session,'row': row, 'cookiejar': i },dont_filter = True)

如您所见,我在每个 scrapy 请求中传递一个 sqlalchemy 行对象。每个行对象都包含空白字段,我从 scrapy 响应中更新这些字段。

def get_PDF(self, response):

    row = response.meta['row']

    row.field1 = response.field1 # simplified pseudocode

现在我想更新行对象,以便将其更改存储在数据库中。 如果我传递 session 对象,我可以执行 session.commit() 。使用 row_object 执行此操作的最佳方法是什么?我需要传递 session 对象吗?

编辑:我已经更改了蜘蛛以传递 session 对象:

def get_PDF(self, response):

    row = response.meta['row']
    session = response.meta['session']

    row =process_output(o, row)
    session.add(row)
    session.commit()

最佳答案

我想说始终处理数据库和“外部”存储的最佳方法是使用 Pipeline ,因为它是一种分离代码逻辑的方法。管道仅处理蜘蛛返回的项目,因此您无需担心请求或蜘蛛代码内的其他内容。

管道还会创建一个与爬虫关联的对象,并且仅实例化一次,这对于这种 session 情况非常有帮助。

如果您需要以不同的方式处理项目,您始终可以向每个项目发送唯一标识符,以便管道知道如何处理每个项目。

编辑: 要在蜘蛛内部创建 Session 对象并在管道中重用它,您可以执行以下操作:

蜘蛛:

def start_requests(self):
    self.session = Session()

管道

def process_item(self, item, spider):
    ...
    spider.session.commit()

那个spider是整个爬虫的“唯一”spider实例,因此您可以在那里使用它的属性。

关于python - 在Scrapy中使用Sqlalchemy更新表行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47943534/

相关文章:

python - 我想从文件中读取并抓取每个 URL

python - 即使通过 Django 中间件重定向后请求仍继续

python - 不知道如何删除sqlalchemy 1.4关于cache_ok的警告

python - Flask-Sqlalchemy 多个数据库(绑定(bind))具有相同的模型(类 DB.Model)

python - SQLAlchemy Core - INSERT IGNORE 和 ON DUPLICATE KEY UPDATE

python - 导入错误 : cannot import name ScrapyFileLogObserver

python - 如何配置 Airflow dag 每天运行两次

python - 完全相同的 python3 代码在 shell 中工作但不在脚本中工作?

python - pysqlite2 : ProgrammingError - You must not use 8-bit bytestrings

python - Django、Django Dynamic Sc​​raper、Djcelery 和 Scrapyd - 不在生产中发送任务