1

parse_items我的蜘蛛中有这段代码

 def parse_items(self, response):

        hxs = HtmlXPathSelector(response)
        sites = hxs.select("//li[@class='mod-result-entry  ']")
        items = []


        for site in sites[:2]:
            item = MyItem()
            item['title'] = myfilter(site.select('dl/a').select("string()").extract())
            item['company'] = myfilter(site.select('dl/h2/em').select("string()").extract())
            items.append(item)
        return items

现在我想使用 Django 模型将项目保存在数据库中。一种工作正常的方法,我像这样简单地使用

item = MYapp.MyDjangoItem()
item.title = myfilter(site.select('dl/a').select("string()").extract())
item.save()

现在这工作正常

现在我想知道这种方法可以很好地保存在数据库中。

我的意思是为什么我们需要在 scrapy 中描述的 itempipeline 东西。这有什么好处吗。

开火,例如,这是我的管道

class MyPipeline(object):

    def __init__(self):
        self.ids_seen = set()

    def process_item(self, item, spider):
       Myitem = Myapp.DjamgoItem()
       Myitem.title = item['title']
       MyItem.save()

这样好吗

另外,我的代码将如何调用此管道。我对此感到困惑

4

1 回答 1

1

管道可用于清理常见值。如果您只有一种类型的对象,这将特别有用。通过管道保存您的 django 模型实例很好,scrapy 文档中的示例通过将 JsonWriter 添加到管道来执行相同的操作。(这在现实生活中是不必要的,因为有内置功能)

把想法大声说出来:

但是,当您创建多个对象时,您可能希望区分您的处理。因为蜘蛛作为参数传递给 process_item 函数,这很容易,但是(imo),这往往会变得相当冗长:

class MyPipeline(object):
    def process_item(self, item, spider):
       if spider == 'A':
           if item.somefield:
               #... etc
       elif spider == 'B':
           #... etc

就我个人而言,我喜欢 Django 中表单清理背后的想法(通过以“clean_”开头的字段名称检查现有函数)。为了在 scrapy 中实现类似的功能,我扩展了 Item 类:

class ExtendedItem(Item):
    def _process(self):
        [getattr(self, func)() for func in dir(self) if func.split('_')[-1] in self.fields and callable(getattr(self, func))]

因此,现在您可以执行以下操作:

class Book(ExtendedItem):
    title = Field()

    def _process_title(self):
        title = self['title'].lower()
        self.update(title=title)

在这种情况下,您可以使用管道调用 item._process() 。

免责声明

不久前我在github.com上提出了这个想法。可能有更好的实现(代码方面)。

于 2012-12-11T09:51:13.873 回答