2017-01-26 194 views
0

我想要加載兩個項目到項目加載程序,通過response.meta命令實例化。不知怎的,標準:項目加載程序不能與response.meta一起工作

loader.add_xpath('item', 'xpath') 

不工作(即沒有值被保存或書面的,它就像「項目」永遠不會創建),但具有完全相同的表達:

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。

回答

0

發生這種情況是因爲您正在執行具有自己的選擇器對象的加載器引用。
在這裏,您創建,並與參考分配選擇參數:

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框架有關(scrapy使用它的併發性)。
什麼,但是你應該做的是負載,並在每一步重建項目:

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) 
+0

真正偉大的回答,非常感謝爲明確寫出如何在第一解析產量scrapy.Request部分的代碼。成功了! – Svarto

相關問題