gpt4 book ai didi

python - 使用 ItemLoader 跨多个响应加载项目字段

转载 作者:行者123 更新时间:2023-12-01 01:18:18 25 4
gpt4 key购买 nike

这是问题 Scrapy: populate items with item loaders over multiple pages 已接受答案的后续问题。我想使用 ItemLoader 将多个请求中的值收集到单个 Item。接受的答案表明加载的 Item.load_item() 应通过 request 中的 meta 字段传递到下一个请求。

但是,我想在爬网结束时返回加载的对象时将 output_processors 应用于单个字段的所有收集值。

问题

  1. 实现这一目标的最佳方法是什么?
  2. 我可以通过 metaItemLoader 实例传递给下一个 request 而不加载它,然后只替换 selector添加下一个响应中的值或 xpath 时,ItemLoader 中的 > 或 response 元素?

示例:

def parse(self, response):
loader = TheLoader(item=TestItems(), response=response)
loader.add_xpath('title1', '//*[@id="firstHeading"]/text()')
request = Request(
"https://en.wikipedia.org/wiki/2016_Rugby_Championship",
callback=self.parsePage1,
meta={'loader': loader},
dont_filter=True
)
yield request

def parsePage1(self, response):
loader = response.meta['loader']
loader.response = response
loader.add_xpath('title1', '//*[@id="firstHeading"]/text()')
return loader.load_item()

忽略实际网站的上下文。

最佳答案

是的,您可以只传递 ItemLoader 实例。

如果我很久以前从 irc 或 github 聊天中正确地记得这一点,那么这样做可能会出现一些潜在的问题,例如内存使用量增加或引用处理泄漏,因为您携带了对象引用ItemLoader 实例(和处理器?),并且可能会持续很长时间,具体取决于下载队列的顺序,通过将这些 itemloader 实例绑定(bind)到这些请求。因此请记住这一点,也许要小心在大型爬网中使用这种风格,或者进行一些内存调试来确定。

但是,我自己过去广泛使用过这种方法(并且在使用 ItemLoaders 时仍然会这样做),并且我自己没有发现这种方法有任何问题。

我是这样做的:

import scrapy
from myproject.loader import ItemLoader

class TheLoader(ItemLoader):
pass

class SomeSpider(scrapy.Spider):
[...]

def parse(self, response):
loader = TheLoader(item=TestItems(), response=response)
loader.add_xpath('title1', '//*[@id="firstHeading"]/text()')
request = Request("https://en.wikipedia.org/wiki/2016_Rugby_Championship",
callback=self.parsePage1,
dont_filter=True
)
request.meta['loader'] = loader
yield request

def parsePage1(self, response):
loader = response.meta['loader']
# rebind ItemLoader to new Selector instance
#loader.reset(selector=response.selector, response=response)
# skipping the selector will default to response.selector, like ItemLoader
loader.reset(response=response)
loader.add_xpath('title1', '//*[@id="firstHeading"]/text()')
return loader.load_item()

这需要使用自定义的 ItemLoader 类,可以在 my scrapy scrapyard 中找到该类。 ,但类(class)的相关部分在这里:

from scrapy.loader import ItemLoader as ScrapyItemLoader

class ItemLoader(ScrapyItemLoader):
""" Extended Loader
for Selector resetting.
"""

def reset(self, selector=None, response=None):
if response is not None:
if selector is None:
selector = self.default_selector_class(response)
self.selector = selector
self.context.update(selector=selector, response=response)
elif selector is not None:
self.selector = selector
self.context.update(selector=selector)

关于python - 使用 ItemLoader 跨多个响应加载项目字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54102498/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com