2

我正在研究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 and so on(蜘蛛不限可能更多)>根据蜘蛛的数量和蜘蛛的名字我要创建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 文件应该产生。

  1. 上述代码是否足以满足上述功能?

  2. 我们是否需要创建另一个管道类来创建另一个 csv 文件?(是否可以在单个 pipeline.py 文件中创建多个管道类?)

  3. 如果我们在单个 pipeline.py 文件中创建多个管道类,如何将特定蜘蛛与其相关的管道类匹配

我想在保存到数据库时实现相同的功能,我的意思是当我运行 spider1 时,spider1 的所有数据都应该保存到数据库中,并保存到具有相关蜘蛛名称的表中。这里对于每个蜘蛛我都有不同的 sql 查询(所以需要编写不同的管道类)

  1. 这里的含义是当我们一次运行多个蜘蛛时(使用scrapyd),应该生成多个csv文件及其蜘蛛名称,并且应该使用蜘蛛名称创建多个表(保存到数据库时)

抱歉,如果在任何地方错了,我希望它得到很好的解释,如果没有,请告诉我。

4

1 回答 1

3

你通常是在正确的轨道上。

但有几点我可以立即指出:

  1. 您可能不需要(=不应该使用)课程!Python 不是 Java。如果您的类仅包含 2 个方法,而第一个是__init__-method,那么您几乎可以肯定不需要类,但函数就可以了。更少的混乱 = 更好的代码!

  2. SO 不适合进行一般的代码审查。改用codereview。SO 用户是一群友好(大部分)且乐于助人的人,但他们不喜欢编写您的代码。他们喜欢解释、建议和纠正。因此,尝试实现您的应用程序,如果遇到麻烦您自己无法解决,请再次回来寻求建议。如上所述,您在概念上处于正确的轨道上,只需尝试实现它。

  3. 您似乎对班级概念有误解。至少只要它是 python 类:

    1. 据我所知,您不需要 BaseSpider 类。基类和子类之间有什么区别?派生类不会使您的程序面向对象,或者更好,或者其他什么。搜索Liskovs 原则以大致了解子类何时适用于 python。(这有点相反的逻辑,但它是查看是否应该继承或更改方法的最快方法之一。)

    2. 在类声明之后立即声明的 python 类变量和在__init__方法中初始化的实例变量之间存在明显差异。类变量在类的所有实例之间共享,其中实例变量对各个实例是私有的。你几乎从不想使用类变量,这是一个Singleton-Pattern,在大多数情况下你想避免这种情况,因为它会在调试中引起头痛和不满。

因此我会修改你的Spider-class 像:

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 

但也许您正在使用声明性元类方法,但我无法从您发布的代码中看到这一点。

如果你想并行运行你的爬虫,你应该考虑threading-module。它用于连续的 I/O 操作,而不是multiprocessing用于并行计算的 -module。

你在概念上走在正确的轨道上。将您的项目分解成小块,并在每次遇到错误时返回。

只是不要指望在这样的问题上得到完整的答案:“我不想重新创建谷歌,我怎样才能以最好的方式和最短的时间做到这一点!” ;-)

于 2012-07-06T09:40:56.137 回答