【发布时间】:2018-08-22 23:19:36
【问题描述】:
我编写了一些从不同来源提取相似数据的蜘蛛。我还编写了一个管道,允许将这些数据放入数据库中。我希望能够为多个蜘蛛使用相同的代码输出到不同的表,从蜘蛛名称动态命名。
这里是pipeline.py 代码:
class DbPipeline(object):
def __init__(self):
"""
Initialises database connection and sessionmaker.
Creates table if it doesn't exist.
"""
engine = db_connect()
create_output_table(engine)
self.Session = sessionmaker(bind=engine)
def process_item(self, item, spider):
"""
Saves scraped products in database
"""
exists = self.check_item_exists(item)
if not exists:
session = self.Session()
product = Products(**item)
try:
session.add(product)
session.commit()
except:
session.rollback()
raise
finally:
session.close()
return item
def check_item_exists(self,item):
session = self.Session()
product = Products(**item)
result = session.query(Products).filter(Products.title == item['title']).first()
return result is not None
这里是model.py 文件:
DeclarativeBase = declarative_base()
def create_output_table(engine):
DeclarativeBase.metadata.create_all(engine)
def db_connect():
"""
Connects to database from settings defined in settings.py
Returns an sqlalchemy engine instance
"""
return create_engine(URL(**settings.DATABASE))
class Products(DeclarativeBase):
"""Sqlalchemy table model"""
__tablename__ = "name"
id = Column(Integer, primary_key=True)
title = Column('title', String(200))
price = Column('price', String(10), nullable=True)
url = Column('url', String(200), nullable=True)
我想要做的是让__tablename__ 变量与蜘蛛名称相同,我可以在process_item 函数中轻松做到这一点,因为它传递了一个spider 对象并且可以使用@ 987654330@ 并将其分配给类变量,但是该函数将在创建/定义表后运行。如何在pipelines.py 文件中的process_item 函数之外获取蜘蛛名称?
编辑:我已经尝试了How to access scrapy settings from item Pipeline 中列出的解决方案,但是访问“设置”并不能访问分配给当前正在运行的蜘蛛的属性。我需要根据运行管道的蜘蛛动态获取蜘蛛的名称。谢谢
【问题讨论】:
-
@gangabass 嘿,我已经更新了我的问题,为什么它不是重复的
-
您想在您的
check_item_exists中获取当前蜘蛛名称吗? -
如果我可以在该文件中的任何位置获取该名称,那将是一些东西,但我需要它真正在产品类中。我目前正在尝试如何使用您链接的帖子中的 from_crawler() 方法,但我不完全确定它会有所帮助。我知道 crawler.spider.name 可能有效,但不确定这是否只会返回 DefaultSpider 名称而不是当前正在运行的名称。
标签: python-3.x sqlalchemy scrapy