我希望将两个项加载到一个项目加载器中,通过response.meta命令进行实例化。不知何故,标准:
loader.add_xpath('item', 'xpath')不工作(即没有保存或写入值,它就像从未创建过的“item”),但是使用完全相同的表达式:
response.xpath('xpath)
loader.add_value('item',value) 有用吗?现在有人知道为什么吗?完整代码如下:
Spider.py
def parse(self, response):
for record in response.xpath('//div[@class="box list"]/div[starts-with(@class,"record")]'):
loader = BaseItemLoader(item=BezrealitkyItems(), selector=record)
loader.add_xpath('title','.//div[@class="details"]/h2/a[@href]/text()')
listing_url = record.xpath('.//div[@class="details"]/p[@class="short-url"]/text()').extract_first()
yield scrapy.Request(listing_url, meta={'loader' : loader}, callback=self.parse_listing)
def parse_listing(self, response):
loader = response.meta['loader']
loader.add_value('url', response.url)
loader.add_xpath('lat','//script[contains(.,"recordGps")]',re=r'(?:"lat":)[0-9]+\.[0-9]+')
return loader.load_item()上面的方法不起作用,但当我尝试这样做时,它是有效的:
lat_coords = response.xpath('//script[contains(.,"recordGps")]/text()').re(r'(?:"lat":)([0-9]+\.[0-9]+)')
loader.add_value('lat', lat_coords)我的item.py没有什么特别之处:
class BezrealitkyItems(scrapy.Item):
title = scrapy.Field()
url = scrapy.Field()
lat = scrapy.Field()
class BaseItemLoader(ItemLoader):
title_in = MapCompose(lambda v: v.strip(), Join(''), unidecode)
title_out = TakeFirst()为了澄清,我没有收到错误信息。它只是'lat‘项目没有被创建,也没有被刮到它。其他项目都是很好的,包括也通过parse_listing函数添加的url。
发布于 2017-01-27 02:27:17
发生这种情况是因为您正在传递加载器引用,该引用具有自己的选择器对象。
在这里,使用引用创建并分配选择器参数:
loader = BaseItemLoader(item=BezrealitkyItems(), selector=record)现在,您将这个加载程序放入您的Request.meta属性中,并将其传递到下一个解析方法。但是,您没有做的是在从元中检索加载程序之后更新选择器上下文:
loader = response.meta['loader']
# if you check loader.selector you'll see that it still has html body
# set in previous method, i.e. selector of record in your case
loader.selector = Selector(response) # <--- this is missing但是,这是可以避免的,因为在meta中拥有大量引用的复杂对象是个坏主意,并且可能导致所有类型的错误,这些错误大多与Twisted框架有关(因为它的并发性而被刮擦地使用)。
但是,您应该做的是在每一步中加载和重新创建项:
def parse(self, response):
loader = BaseItemLoader(item=BezrealitkyItems(), selector=record)
yield scrapy.Request('some_url', meta={'item': loader.load_item()}, callback=self.parse2)
def parse2(self, response):
loader = BaseItemLoader(item=response.meta['item'], selector=record)https://stackoverflow.com/questions/41880200
复制相似问题