2015-08-27 4 views
7
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 

Ну, я очищаю всю таблицу в основном методе анализа, и я взял несколько полей из этой таблицы. Одним из этих полей является URL-адрес, и я хочу изучить его, чтобы получить целую новую группу полей. Как передать мой уже созданный объект ITEM функции обратного вызова, чтобы конечный элемент сохранял все поля?Передача аргумента функции обратного вызова

Как показано в приведенном выше коде, я могу сохранить поля внутри url (код в данный момент) или только те, что указаны в таблице (просто напишите yield item) , но я не могу дать только один объект со всеми полями вместе.

Я пробовал это, но, очевидно, он не работает.

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

Try, чтобы посмотреть на декораторы, например. http://thecodeship.com/patterns/guide-to-python-function-decorators/ – Sumido

+0

Итак, url возвращает поля, которые не присутствуют в 'item', и вы хотите добавить эти поля в' item' и вернуть его? –

+0

Вам удалось сделать эту работу? – briankip

ответ

14

Это то, что вы хотите использовать 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.

0

У меня была аналогичная проблема с дополнительным аргументом мимоходом 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) 
+1

Это опасное предложение. Он перебирает все «элементы», найденные в 'response.xpath ('// tbody/tr')'. Поскольку Request не будет предоставлять элемент в качестве параметра в обратном вызове (когда-либо), метод обработчика всегда будет использовать элемент по умолчанию. К сожалению, элемент будет тем, чем он является * во время вызова обратного вызова *, а не тем, что было в момент запроса. Ваши собранные данные будут ненадежными и непоследовательными. – Rejected

+0

@Rejected Нет, назначая переменные в заголовке функции (self = self ...), он сохраняет значения переменных во время определения функции 'handler'. так долго определение 'handler' находится внутри цикла,' parse_profile' получит значения каждого элемента, который будет переименован. –

+0

Это красиво изящное решение. –

Смежные вопросы