寻找一种更好的方法来处理一个 url 中的所有项目

Looking for a better way to handle all items from one url

我有一个蜘蛛来抓取 url 的列表,例如

class MySpider(scrapy.Spider):
    name = 'example.com'
    allowed_domains = ['example.com']
    start_urls = [
        'http://www.example.com/1.html',
        'http://www.example.com/2.html',
        'http://www.example.com/3.html',
    ]
 def parse(self, response):
    items = []
    records = response.xpath('//*[@id="feed-main-list"]/li')
    for rec in records:
        item = MyItem()
        item['spiderUrl'] = response.request.url
        item['url']     = rec.xpath('.//*[@class="feed-block-title"]/a/@href').extract_first().strip()
        item['title']   = rec.xpath('string(.//*[@class="feed-block-title"])').extract_first().strip()
        item['lastUpdate'] = 'success'
        items.append(item)
    return items

对于每个 url,我需要尽快一起处理这些项目(分析数据,如果有事情就发送电子邮件)。我选择管道来做。但是在管道中,它只是从 from 中一个接一个地接收项目。 因此,我尝试将物品打包到蜘蛛中的一个容器物品中。 在蜘蛛中,

container = ContainerItem()
container['url'] = response.request.url
container['itemist'] = items
return [container]

并在筹备中,

> def process_item(self, item, spider):
>     item['itemList']
>     n = len(item['itemList'])
>     for i in item['itemList']:
>         item = dict(i)
>         ...

所以,我的问题是: 1、按照我的要求,这样实现好吗? 2. 像这样将一个项目列表打包到一个容器项目中看起来非常难看。有什么Scrapy风格的方法吗?

谢谢!

我认为最合乎逻辑的解决方案是将所有项目合并为一个。嵌套在字典中是一个非常常见的概念,它可能看起来很复杂和肮脏,但实际上是最佳且简单的,只要你不深入 10 层。

要做到这一点,只需将您的 items 列表包装在字典中,例如:

def parse(self, response):
    items = []
    records = response.xpath('//*[@id="feed-main-list"]/li')
    for rec in records:
        item = MyItem()
        item['spiderUrl'] = response.request.url
        item['url']     = rec.xpath('.//*[@class="feed-block-title"]/a/@href').extract_first().strip()
        item['title']   = rec.xpath('string(.//*[@class="feed-block-title"])').extract_first().strip()
        item['lastUpdate'] = 'success'
        items.append(item)
    return {'items': items}

现在您的管道将接收所有项目作为一个项目,您可以解包、分类并执行任何您想要的操作。
在 scrapy 中,这种方法非常普遍,如果使用 ItemLoader 而不是纯 scrapy.Item,甚至可以与 ItemLoader 一起使用,澄清一下,只是稍微修改了 python 字典!