2015-12-12 3 views
0

Я пытаюсь получить Scrapy для запуска пауков для большого количества URL-адресов, которые я сохранил в БД.Scrapy with Django- Pass больше информации, что только URL

«Пауки» все работают нормально.

У меня возникли проблемы с тем, что Scrapy «помнит», с какими объектами он работает. В приведенном ниже коде используется поле URL для сопоставления его с моей базой данных django.

Проблема заключается в том, что URL-адрес часто может меняться при его доступе в браузере, поэтому scrapy не знает, куда помещать данные.

В идеале, я мог бы просто рассказать первичный ключ объекта - удалить всю комнату для ошибки.

import sys, os, scrapy, django 
from scrapy.crawler import CrawlerProcess 
from scrapy.exceptions import DropItem 

## Django init ## 
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) ## direct to where manage.py is 

os.environ['DJANGO_SETTINGS_MODULE'] = 'XYZDB.settings' 
django.setup() 

################# 

## Settings ## 

#queryset_chunksize = 1000 

############## 

    from XYZ import models 
    from parsers import dj, asos, theiconic 

    stores = [dj, asos, theiconic] 



    parsers = dict((i.domain, i) for i in stores) 

    def urls(): 
     for i in models.Variation.objects.iterator(): 
      yield i.link_original if i.link_original else i.link 


    class Superspider(scrapy.Spider): 
     name = 'Superspider' 

     start_urls = urls() 

     def parse(self, response): 
      for i in parsers: 
       if i in response.url: 
        return parsers[i].parse(response) 


    ## Reference - models 
    ''' 
    Stock_CHOICES = (
     (1, 'In Stock'), 
     (2, 'Low Stock'), 
     (3, 'Out of Stock'), 
     (4, 'Discontinued'), 
    ) 
    ''' 

    class ProductPipeline: 
     def process_item(self, item, spider): 
      var = models.Variation.objects.get(link_original=item['url']) 
      size = models.Size.objects.get(variation=var) 
      if item['stock'] != models.Stock.objects.filter(size=size)[0]: 
       models.Stock(size=size, stock=item['stock']).save() 

      if int(item['price']) != int(models.Price.objects.filter(variation=var)): 
       models.Price(variation=var, price=item['price']).save() 
      return 


    if __name__ == '__main__': 

     process = CrawlerProcess({ 
      'USER_AGENT': 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)', 
      'ITEM_PIPELINES': {'__main__.ProductPipeline': 1,}, 
      'DOWNLOAD_DELAY': 0.4 
      }) 

     process.crawl(Superspider) 
     process.start() 

ответ

0

Вы можете использовать атрибут scrapy response.meta. Замените определение start_urls на процедуру start_requests(self), где вы можете yield Request(your url, meta={'pk': primary key}). Затем вы можете получить доступ к метаданным в процедуре parse(), используя item['pk'] = response.meta['pk']. start_requests() docs.