Scrapy возвращает только первый результат в цикле

У меня есть цикл (как показано ниже), который выполняется дважды (индексы 1->3), но Scrapy возвращает только первое имя дорожки в обоих результатах. Но строка print item показывает разные значения для str_selector, поэтому я знаю, что цикл работает, но Scrapy не видит изменяющегося значения x.

Есть идеи, какую ошибку я совершил?

items = []
item = scrapyItem()

for x in range (1,3):
    str_selector = '//tr[@name="tracks-grid-browse_track_{0}"]/td[contains(@class,"secondColumn")]/a/text()'.format(x)
    item['trackname'] = hxs.select(str_selector).extract()
    print item
    items.append(item)
return items

person zoonosis    schedule 03.09.2012    source источник


Ответы (2)


Просто вы должны создавать новый элемент для каждой итерации, а не оставлять один и тот же: вы добавляете items один и тот же объект, который mutable (как и для всех пользовательских классов по умолчанию в python), поэтому при обновлении item['trackname'] обновляются все содержащиеся элементы!

Вот код для иллюстрации:

>>> class C(object):
        # Basic user-defined class
    def __init__(self):
        self.test = None


>>> c = C()
>>> items = []
>>> for x in range (1,3):
    c.test = x
    print c, c.test
    items.append(c)


<__main__.C object at 0x01CEB130> 1
<__main__.C object at 0x01CEB130> 2
>>> items # All objects contained are the same !!!
[<__main__.C object at 0x01CEB130>, <__main__.C object at 0x01CEB130>]
>>> for c in items:
    print c.test


2
2

Теперь каждый раз создавайте новый объект:

>>> items = []
>>> for x in range (1,3):
    c = C()
    c.test = x
    print c, c.test
    items.append(c)


<__main__.C object at 0x01CEB110> 1
<__main__.C object at 0x011F2270> 2

Объекты теперь другие!

>>> for c in items:
    print c.test


1
2
person Emmanuel    schedule 03.09.2012
comment
Большое спасибо Эммануэль. Работает удовольствие. Я думаю, я понял, что элемент будет менять свое значение каждый раз, когда цикл повторяется. Нубская ошибка :) - person zoonosis; 04.09.2012

что на самом деле вы делаете прямо сейчас, так это создаете объект элемента и изменяете его значение в цикле, вам нужно создать элемент в цикле.

items = []
#item = scrapyItem()

for x in range (1,3):
    item = scrapyItem()
    str_selector = '//tr[@name="tracks-grid-browse_track_{0}"]/td[contains(@class,"secondColumn")]/a/text()'.format(x)
    item['trackname'] = hxs.select(str_selector).extract()
    print item
    items.append(item)
return items
person akhter wahab    schedule 03.09.2012
comment
Спасибо за вашу помощь в этом. Очень признателен. - person zoonosis; 04.09.2012