def parse(self, response):
for sel in response.xpath('//tbody/tr'):
item = HeroItem()
item['hclass'] = response.request.url.split("/")[8].split('-')[-1]
item['server'] = response.request.url.split('/')[2].split('.')[0]
item['hardcore'] = len(response.request.url.split("/")[8].split('-')) == 3
item['seasonal'] = response.request.url.split("/")[6] == 'season'
item['rank'] = sel.xpath('td[@class="cell-Rank"]/text()').extract()[0].strip()
item['battle_tag'] = sel.xpath('td[@class="cell-BattleTag"]//a/text()').extract()[1].strip()
item['grift'] = sel.xpath('td[@class="cell-RiftLevel"]/text()').extract()[0].strip()
item['time'] = sel.xpath('td[@class="cell-RiftTime"]/text()').extract()[0].strip()
item['date'] = sel.xpath('td[@class="cell-RiftTime"]/text()').extract()[0].strip()
url = 'https://' + item['server'] + '.battle.net/' + sel.xpath('td[@class="cell-BattleTag"]//a/@href').extract()[0].strip()
yield Request(url, callback=self.parse_profile)
def parse_profile(self, response):
sel = Selector(response)
item = HeroItem()
item['weapon'] = sel.xpath('//li[@class="slot-mainHand"]/a[@class="slot-link"]/@href').extract()[0].split('/')[4]
return item
さて、私はメインの解析メソッドでテーブル全体をかき集めており、そのテーブルからいくつかのフィールドを取得しています。これらのフィールドの1つはURLであり、まったく新しいフィールドを取得するためにそれを探索したいと考えています。作成済みのITEMオブジェクトをコールバック関数に渡して、最終的なアイテムがすべてのフィールドを保持する方法を教えてください。
上記のコードに示されているように、URL内のフィールド(現時点ではコード)またはテーブル内のフィールドのみを保存できます(単にyield item
)しかし、すべてのフィールドを一緒にしたオブジェクトを1つだけ生成することはできません。
私はこれを試しましたが、明らかに機能しません。
yield Request(url, callback=self.parse_profile(item))
def parse_profile(self, response, item):
sel = Selector(response)
item['weapon'] = sel.xpath('//li[@class="slot-mainHand"]/a[@class="slot-link"]/@href').extract()[0].split('/')[4]
return item
これがmeta
キーワードを使用する目的です。
_def parse(self, response):
for sel in response.xpath('//tbody/tr'):
item = HeroItem()
# Item assignment here
url = 'https://' + item['server'] + '.battle.net/' + sel.xpath('td[@class="cell-BattleTag"]//a/@href').extract()[0].strip()
yield Request(url, callback=self.parse_profile, meta={'hero_item': item})
def parse_profile(self, response):
item = response.meta.get('hero_item')
item['weapon'] = response.xpath('//li[@class="slot-mainHand"]/a[@class="slot-link"]/@href').extract()[0].split('/')[4]
yield item
_
また、sel = Selector(response)
を実行することはリソースの浪費であり、以前に行ったこととは異なるため、変更しました。これは自動的にresponse
に_response.selector
_としてマップされます。これには_response.xpath
_の便利なショートカットもあります。
Argsをコールバック関数に渡すより良い方法は次のとおりです。
def parse(self, response):
request = scrapy.Request('http://www.example.com/index.html',
callback=self.parse_page2,
cb_kwargs=dict(main_url=response.url))
request.cb_kwargs['foo'] = 'bar' # add more arguments for the callback
yield request
def parse_page2(self, response, main_url, foo):
yield dict(
main_url=main_url,
other_url=response.url,
foo=foo,
)
Tkinterの余分な引数の受け渡しに同様の問題があり、この解決策が機能することがわかりました(ここ: http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/extra-args.html )、あなたの問題に変換されます:
def parse(self, response):
item = HeroItem()
[...]
def handler(self = self, response = response, item = item):
""" passing as default argument values """
return self.parse_profile(response, item)
yield Request(url, callback=handler)