2017-01-26 14 views
0

アイテムローダーに2つのアイテムをロードします。これは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属性にこのローダーを入れて、次の構文解析メソッドに持ち越さ。あなたはメタからローダーを取得したら、あなたはかかわらず、行っていないと、セレクタのコンテキストを更新しています:metaでの参照の多くの複雑なオブジェクトを持つことは、Aであるので、これはうまくいく

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 

、しかしそれは避けるべきです悪い考えであり、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) 
+0

を本当に素晴らしい答え、たくさん明示的に最初の解析では降伏scrapy.Request部分をコードする方法を記述するための感謝:あなたはしかし、何をすべき
は、負荷とすべてのステップでアイテムを再作成です。働いた! – Svarto

関連する問題