如何在scrapy python中使用蜘蛛名称动态创建csv文件

时间:2012-07-05 12:04:30

标签: python csv scrapy pipeline web-crawler

我正在研究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只蜘蛛(使用报废),当我运行所有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文件中创建多个管道类,如何将特定的spider与其相关的管道类匹配

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

    1. 这里的内容是当我们一次运行多个蜘蛛(使用scrapyd)时,应该使用蜘蛛名称生成多个csv文件,并且应该使用蜘蛛名称创建多个表(当保存到数据库时)
    2. 对不起,如果我在任何地方都错了,我希望它能得到很好的解释,如果没有,请告诉我。

1 个答案:

答案 0 :(得分:3)

您通常走在正确的轨道上。

但我可以立即指出一些观点:

  1. 你可能不需要(=不应该使用)一个班级! Python不是Java。如果你的类只包含2个方法,而第一个是__init__ - 方法,你几乎肯定不需要一个类,但函数会很好。减少杂乱=更好的代码!

  2. SO不适合进行常规代码审核。请尝试使用codereview。 SO-useres是一个友好的(大多数)和有用的人,但他们不喜欢编写你的代码。他们喜欢解释,建议和纠正。 因此,尝试实施您的应用程序,如果您遇到麻烦,您无法解决自己,请再次回来并寻求建议。如上所述,您在概念上走上正轨,只是尝试实现它。

  3. 你似乎对课堂概念有误解。至少只要它是python-classes:

    1. 就我所见,您不需要BaseSpider类。基类和子类之间有什么区别?派生类不会使你的程序成为OO,或者更好,或者其他什么。搜索Liskovs principle以便大致了解子类何时适合python。 (这有点像反向逻辑,但它是了解你是否应该继承或改变你的方法的最快方法之一。)

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

  4. 因此我会修改你的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 
    

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

    如果您想并行运行抓取工具,则应考虑threading - 模块。它适用于与multiprocessing - 模块相对的连续I / O操作,用于并行计算。

    你的概念正好在正确的轨道上。将项目分成小块,每次遇到错误都会返回。

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