自定义BaseSpider Scrapy

时间:2017-06-17 18:11:40

标签: python scrapy scrapy-spider

我想在自定义基类蜘蛛类中为蜘蛛提供一些通用功能。

通常scrapy蜘蛛继承自scrapy.Spider类。

我尝试在scrapy的spiders文件夹中创建一个没有工作的BaseSpider类

import scrapy


class BaseSpider(scrapy.Spider):
    def __init__(self):
        super(scrapy.Spider).__init__()

    def parse(self, response):
        pass

这是我真正的蜘蛛

import scrapy
import BaseSpider


class EbaySpider(BaseSpider):
    name = "ebay"
    allowed_domains = ["ebay.com"]

    def __init__(self):
        self.redis = Redis(host='redis', port=6379)
    # rest of the spider code

给出此错误

TypeError: Error when calling the metaclass bases
    module.__init__() takes at most 2 arguments (3 given)

然后我尝试使用多重继承并使我的ebay蜘蛛看起来像

class EbaySpider(scrapy.Spider, BaseSpider):

    name = "ebay"
    allowed_domains = ["ebay.com"]

    def __init__(self):
        self.redis = Redis(host='redis', port=6379)
    # rest of the spider code 

给出了

TypeError: Error when calling the metaclass bases

metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases

我是python和scrapy的新手,我正在尝试在其中实现我的PHP编码风格,我认为它不起作用。

我正在寻找合适的方法。

由于

更新

根据scrapy.Spider

更改 init 签名

BaseSpider

def __init__(self, *args, **kwargs):
        super(scrapy.Spider, self).__init__(*args, **kwargs)

EbaySpider

class EbaySpider(BaseSpider):
    def __init__(self, *args, **kwargs):
        super(BaseSpider,self).__init__(*args, **kwargs)
        self.redis = Redis(host='redis', port=6379)

还在

File "/scrapper/scrapper/spiders/ebay.py", line 11, in <module>
    class EbaySpider(BaseSpider):
TypeError: Error when calling the metaclass bases
    module.__init__() takes at most 2 arguments (3 given)

1 个答案:

答案 0 :(得分:5)

查看scrapy.Spider.__init__ signature

def __init__(self, name=None, **kwargs):
    # ...

子类应定义具有相同签名的__init__方法。如果您不关心名称和kwargs,只需将它们传递给基类:

class BaseSpider(scrapy.Spider):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

    def parse(self, response):
        pass

如果它已经从BaseSpider继承,那么EbaySpider不必从scrapy.Spider继承。它也应该具有相同的__init__签名,并且还需要调用super()

class EbaySpider(BaseSpider):

    name = "ebay"
    allowed_domains = ["ebay.com"]

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.redis = Redis(host='redis', port=6379)

(我正在使用{3}}的Python 3语法

修改

还有一个问题:您正在导入BaseSpider:

super()

可能你有一个名为BaseSpider(BaseSpider.py文件)的模块,以及一个名为BaseSpider的类。 import BaseSpider 为您提供模块对象,而不是蜘蛛类。尝试使用import BaseSpider,并更好地重命名模块以避免混淆并遵循pep-8