我正在使用scrapy,我有以下功能管道类:
class DynamicSQLlitePipeline(object):
@classmethod
def from_crawler(cls, crawler):
# Here, you get whatever value was passed through the "table" parameter
docket = getattr(crawler.spider, "docket")
return cls(docket)
def __init__(self,docket):
try:
db_path = "sqlite:///"+settings.SETTINGS_PATH+"\\data.db"
db = dataset.connect(db_path)
table_name = docket[0:3] # FIRST 3 LETTERS
self.my_table = db[table_name]
except Exception:
# traceback.exec_print()
pass
def process_item(self, item, spider):
try:
test = dict(item)
self.my_table.insert(test)
print('INSERTED')
except IntegrityError:
print('THIS IS A DUP')
我的蜘蛛中有:
custom_settings = {
'ITEM_PIPELINES': {
'myproject.pipelines.DynamicSQLlitePipeline': 600,
}
}
从最近的一个问题我被指出What is the 'cls' variable used for in Python classes?
如果我正确理解为了实例化管道对象(使用init函数),它需要一个案卷号。只有运行from_crawler类方法后才能使用文档编号。但是什么触发了from_crawler方法。代码再次起作用。
答案 0 :(得分:2)
classmethod的调用者必须拥有该类的实例。他们可能只是通过名称访问它,如下所示:
DynamicSQLlitePipeline.from_crawler(crawler)
......或:
sqlitepipeline.DynamicSQLlitePipeline.from_crawler(crawler)
或许您可以将类对象传递给某人,然后将它们存储起来并在以后使用它:
pipelines[i].from_crawler(crawler)
在Scrapy中,根据the docs,使用框架注册一组管道的常用方法是这样的:
ITEM_PIPELINES = {
'myproject.pipelines.PricePipeline': 300,
'myproject.pipelines.JsonWriterPipeline': 800,
}
(另请参阅Extensions user guide,其中说明了这适用于scrapy项目。)
据推测,你已经在代码中做了类似的事情,你没有向我们展示过,把'sqlscraper.pipelines.DynamicSQLlitePipeline'
放在那个字典中。在某些时候,Scrapy会通过该dict,按值按顺序对其进行排序,并实例化每个管道。 (因为它具有类的名称,作为字符串,而不是类对象,这有点棘手,但这里的细节实际上并不相关。)