Да, вы можете просто передать экземпляр ItemLoader
.
Если я правильно помню это из чата irc или github давным-давно, могут иметь некоторые потенциальные проблемы с этим, такие как увеличение использования памяти или утечки из обработки ссылок, потому что вы переносите ссылки на объекты Экземпляры ItemLoader (и процессоры?) И, возможно, в течение длительного времени, в зависимости от порядка очередей загрузки, путем привязки этих экземпляров ItemLoader к этим запросам.
Так что имейте это в виду и, возможно, остерегайтесь использования этого стиля на больших обходах или сделайте некоторую отладку памяти, чтобы быть уверенным.
Однако в прошлом я сам широко использовал этот метод (и все равно делал бы это при использовании 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
, который можно найти в мой помойный скребок ,
но соответствующая часть класса находится здесь:
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)