寻找一种更好的方法来处理一个 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 字典!
我有一个蜘蛛来抓取 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 字典!