我正在使用 scrapy 并抓取了一个网站并获取了所有信息
实际上我有 3 个具有不同数据的蜘蛛,我在同一个文件夹中创建了这 3 个蜘蛛 具有以下结构
scrapy.cfg
myproject/
__init__.py
items.py
pipelines.py
settings.py
spiders/
__init__.py
spider1.py
spider2.py
spider3.py
现在,当我们运行该特定蜘蛛时,我需要通过管道使用该蜘蛛名称创建一个 csv 文件,例如
spider1.csv,spider2.csv,spider3.csv等
(蜘蛛不限制可能会更多)>根据我要创建的csv文件的蜘蛛数量和蜘蛛名称
这里我们是否可以在 pipeline.py 中创建多个管道?如果存在多个蜘蛛,还如何动态创建带有蜘蛛名称的 csv 文件
这里我有 3 个蜘蛛,我想一次运行所有 3 个蜘蛛(通过使用 scrapyd),当我运行所有 3 个蜘蛛时,应该创建 3 个带有蜘蛛名称的 csv 文件。 我想安排这个蜘蛛每 6 小时运行一次。 如果我的解释有问题,请纠正我并让我知道如何实现这一目标。
提前致谢
编辑后的代码: 例如,我仅粘贴 Spider1.py 的代码
spider1.py中的代码:
class firstspider(BaseSpider):
name = "spider1"
domain_name = "www.example.com"
start_urls = [
"www.example.com/headers/page-value"
]
def parse(self, response):
hxs = HtmlXPathSelector(response)
........
.......
item = Spider1Item()
item['field1'] = some_result
item['field2'] = some_result
.....
.....
return item
Pipeline.py代码:
import csv
from csv import DictWriter
class firstspider_pipeline(object):
def __init__(self):
self.brandCategoryCsv = csv.writer(open('../%s.csv' % (spider.name), 'wb'),
delimiter=',', quoting=csv.QUOTE_MINIMAL)
self.brandCategoryCsv.writerow(['field1', 'field2','field3','field4'])
def process_item(self, item, spider):
self.brandCategoryCsv.writerow([item['field1'],
item['field2'],
item['field3'],
item['field4'])
return item
正如我之前所说,当我使用蜘蛛名称运行上述蜘蛛时,将动态创建一个包含蜘蛛名称的 csv 文件......
但是现在,当我运行其余的蜘蛛(例如 spider2,spider3,spider3
)时,应该生成带有相应蜘蛛名称的 csv 文件。
上述代码是否足以实现上述功能?
是否需要创建另一个管道类来创建另一个 csv 文件?(是否可以在单个 pipeline.py 文件中创建多个管道类?)
如果我们在单个 pipeline.py 文件中创建多个管道类,如何将特定的蜘蛛与其相关的管道类相匹配
我想在保存到数据库时实现相同的功能,我的意思是当我运行spider1时,spider1的所有数据都应该保存到数据库到具有相对spider名称的表中。 这里对于每个蜘蛛我有不同的sql查询(因此需要编写不同的管道类)
- 这里的意思是,当我们同时运行多个蜘蛛时(使用scrapyd),应该生成多个带有蜘蛛名称的csv文件,并且应该使用蜘蛛名称创建多个表(保存到数据库时)
抱歉,如果有任何错误,我希望能得到很好的解释,如果没有,请告诉我。
最佳答案
您总体上走在正确的道路上。
但是有一些我可以立即指出的点:
您可能不需要(=不应该使用)类(class)! Python 不是 Java。如果您的类仅包含 2 个方法,并且第一个方法是 __init__ 方法,那么您几乎肯定不需要类,但函数就可以了。更少的困惑 = 更好的代码!
SO 不适合进行一般代码审查。试试codereview反而。 SO-useres 是一群友好(大部分)且乐于助人的人,但他们不喜欢编写您的代码。他们喜欢解释、建议和纠正。 所以尝试实现你的应用程序,如果遇到麻烦你无法自己解决,请再次回来寻求建议。如上所述,您在概念上走在正确的轨道上,只需尝试实现它即可。
您似乎对类概念有误解。至少只要它是 python 类:
据我所知,您不需要 BaseSpider 类。基类和子类之间有什么区别?派生类并不会让你的程序面向对象,或者更好,或者其他什么。搜索 Liskovs principle大致了解子类何时适合 Python。 (这有点逆向逻辑,但它是判断是否应该子类化或更改方法的最快方法之一。)
在类声明之后立即声明的 Python 类变量和在 __init__ 方法中初始化的实例变量之间存在明显区别。类变量在类的所有实例之间共享,其中实例变量对于各个实例来说是私有(private)的。您几乎不想使用类变量,这是一种单例模式,在大多数情况下您希望避免这种情况,因为它会在调试中引起头痛和不满。
因此我会修改您的 Spider
类,例如:
class Spider(object):
def __init__(self, name, url=None):
self.name = name
self.domain_name = url
self.start_urls = [url]
...
crawlers = [Spider('spider %s' %i) for i in xrange(4)] #creates a list of 4 spiders
但也许您正在使用声明性元类方法,但我无法从您发布的代码中看到这一点。
如果您想并行运行爬虫,您应该考虑线程
模块。它用于连续 I/O 操作,而不是用于并行计算的多处理
模块。
从概念上讲,您走在正确的轨道上。将您的项目分成小块,并在每次遇到错误时返回。
只是不要指望得到诸如以下问题的完整答案:“我不想重新创建 Google,我怎样才能以最好的方式和最短的时间做到这一点!” ;-)
关于python - 如何在 scrapy python 中使用蜘蛛名称动态创建 csv 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11343973/