2016-08-23 4 views
-1

Когда мой паук работает на URL, как this:Почему некоторые из значений полей предметов повторяются в этом Spider Spider?

def parse_subandtaxonomy(self, response): 
item = response.meta['item'] 
for sub in response.xpath('//div[@class = "page-content"]/section'): 
    item['Subcategory'] = sub.xpath('h2/text()').extract() 
    for tax in sub.xpath('ul/li/a'): 
     item['Taxonomy'] = tax.xpath('text()').extract() 
     for href in tax.xpath('@href'): 
      # url = response.urljoin(href.extract()) - > this gave me 301 redirects 
      badurl = urljoin('https://211sepa.org/search/', href.extract()) 
      url = badurl.replace('search?', 'search/?area_served=Philadelphia&', 1) # shut off to test multi-page 
      request = scrapy.Request(url, callback=self.parse_listings) 
      request.meta['item'] = item 
      yield item 

Я получаю этот выход, который я ожидаю:

{"Category": ["Housing"], "Subcategory": ["Affordable Housing"], "Taxonomy": ["Section 8 Vouchers"]} 
{"Category": ["Housing"], "Subcategory": ["Affordable Housing"], "Taxonomy": ["Public Housing"]} 
{"Category": ["Housing"], "Subcategory": ["Affordable Housing"], "Taxonomy": ["Low Income/ Subsidized Rental Housing"]} 
{"Category": ["Housing"], "Subcategory": ["Shelter"], "Taxonomy": ["Homeless Shelters"]} 
{"Category": ["Housing"], "Subcategory": ["Shelter"], "Taxonomy": ["Homeless Shelter Centralized Intake"]} 
{"Category": ["Housing"], "Subcategory": ["Shelter"], "Taxonomy": ["Domestic Violence Shelters"]} 
{"Category": ["Housing"], "Subcategory": ["Shelter"], "Taxonomy": ["Runaway/ Youth Shelters"]} 
{"Category": ["Housing"], "Subcategory": ["Shelter"], "Taxonomy": ["Cold Weather Shelters/ Warming Centers"]} 
{"Category": ["Housing"], "Subcategory": ["Shelter"], "Taxonomy": ["Homeless Shelter for Pregnant Women"]} 
{"Category": ["Housing"], "Subcategory": ["Stay Housed"], "Taxonomy": ["Rent Payment Assistance"]} 
{"Category": ["Housing"], "Subcategory": ["Stay Housed"], "Taxonomy": ["Mortgage Payment Assistance"]} 
{"Category": ["Housing"], "Subcategory": ["Stay Housed"], "Taxonomy": ["Landlord/ Tenant Mediation"]} 
{"Category": ["Housing"], "Subcategory": ["Stay Housed"], "Taxonomy": ["General Dispute Mediation"]} 
{"Category": ["Housing"], "Subcategory": ["Overcome Homelessness"], "Taxonomy": ["Transitional Housing/ Shelter"]} 
{"Category": ["Housing"], "Subcategory": ["Overcome Homelessness"], "Taxonomy": ["Rental Deposit Assistance"]} 
{"Category": ["Housing"], "Subcategory": ["Overcome Homelessness"], "Taxonomy": ["Permanent Supportive Housing"]} 

, но потом, когда я изменить yield item к yield request продолжить в crawl, каждый элемент имеет {"Category": ["Housing"], "Subcategory": ["Overcome Homelessness"], "Taxonomy": ["Permanent Supportive Housing"] ... other item info ... } вместо соответствующей подкатегории и таксономии. Каждый элемент, который я в конечном итоге хочу от каждой таксономии, очищается, но неправильно помечен как описано выше. Любая идея, что происходит?

ответ

0

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

Попробуйте это:

def parse_subandtaxonomy(self, response): 
    for sub in response.xpath('//div[@class = "page-content"]/section'): 
     subcategory = sub.xpath('h2/text()').extract() 
     subcategory = sub.xpath('h2/text()').extract_first() # this just takes first element which is nicer! 
     for tax in sub.xpath('ul/li/a'): 
      item = response.meta['item'].copy() 
      item['Subcategory'] = subcategory 
      item['Taxonomy'] = tax.xpath('text()').extract() 
      for href in tax.xpath('@href'): 
       # url = response.urljoin(href.extract()) - > this gave me 301 redirects 
       badurl = urljoin('https://211sepa.org/search/', href.extract()) 
       url = badurl.replace('search?', 'search/?area_served=Philadelphia&', 1) # shut off to test multi-page 
       request = scrapy.Request(url, 
             callback=self.parse_listings, 
             meta={'item': item}) # you can put meta here directly 
       yield request 
+0

Это сделал это и имеет смысл, спасибо. Также интересно, почему вы использовали 'item = response.meta ['item']. Copy()' вместо просто 'item = response.meta ['item']' –

+0

@g_raham для создания нового, чистого объекта объекта для каждого цикл цикла, чтобы предотвратить сохранение данных из предыдущих циклов цикла. Scrapy Item - это в значительной степени словарь python, и вы можете использовать словарь python вместо Item. – Granitosaurus