Rah*_*eel 0 python scrapy scrapy-spider
我想在自定义基本蜘蛛类中具有一些针对蜘蛛的通用功能。
通常,y抓的蜘蛛从scrapy.Spider类继承。
我尝试在scrapy的spiders文件夹中创建BaseSpider类,但该类无效
import scrapy
class BaseSpider(scrapy.Spider):
def __init__(self):
super(scrapy.Spider).__init__()
def parse(self, response):
pass
Run Code Online (Sandbox Code Playgroud)
这是我真正的蜘蛛
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
Run Code Online (Sandbox Code Playgroud)
给出这个错误
TypeError: Error when calling the metaclass bases
module.__init__() takes at most 2 arguments (3 given)
Run Code Online (Sandbox Code Playgroud)
然后我尝试使用多重继承,使我的eBay Spider看起来像
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
Run Code Online (Sandbox Code Playgroud)
这使
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
Run Code Online (Sandbox Code Playgroud)
我是python的新手,也是scrapy的新手,我想在其中实现我的PHP编码风格,但我想这行不通。
我正在寻找合适的方法。
谢谢
更新
根据scrapy.Spider 更改了初始化签名
BaseSpider
def __init__(self, *args, **kwargs):
super(scrapy.Spider, self).__init__(*args, **kwargs)
Run Code Online (Sandbox Code Playgroud)
易趣蜘蛛
class EbaySpider(BaseSpider):
def __init__(self, *args, **kwargs):
super(BaseSpider,self).__init__(*args, **kwargs)
self.redis = Redis(host='redis', port=6379)
Run Code Online (Sandbox Code Playgroud)
仍在
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)
Run Code Online (Sandbox Code Playgroud)
看一下scrapy.Spider.__init__ 签名:
def __init__(self, name=None, **kwargs):
# ...
Run Code Online (Sandbox Code Playgroud)
子类应定义__init__具有相同签名的方法。如果您不关心名称和名称,只需将它们传递给基类:
class BaseSpider(scrapy.Spider):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
def parse(self, response):
pass
Run Code Online (Sandbox Code Playgroud)
如果EbaySpider已经从BaseSpider继承,则不必从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)
Run Code Online (Sandbox Code Playgroud)
(我使用的是Python 3语法super())
编辑
还有一个问题:您要像这样导入BaseSpider:
import BaseSpider
Run Code Online (Sandbox Code Playgroud)
可能您有一个名为BaseSpider的模块(BaseSpider.py文件),并且在该模块内部有一个名为BaseSpider的类。import BaseSpider给您模块对象,而不是蜘蛛类。尝试使用from BaseSpider import BaseSpider,最好将其重命名以避免混淆并遵循pep-8。