2016-12-30 5 views
2

Ich brauche ein kurzes Echtzeit-Scraping und gebe die resultierenden Daten in meinen Django REST Controller zurück.python django scrapy return item zum controller

versuchen Verwendung scrapy zu machen:

import scrapy 
from scrapy.selector import Selector 

from . models import Product 

class MysiteSpider(scrapy.Spider): 
    name = "quotes" 
    start_urls = [ 
     'https://www.something.com/browse?q=dfd', 
    ] 
    allowed_domains = ['something.com'] 

    def parse(self, response): 
     items_list = Selector(response).xpath('//li[@itemprop="itemListElement"]') 

     for value in items_list: 
      item = Product() 
      item['picture_url'] = value.xpath('img/@src').extract()[0] 
      item['title'] = value.xpath('h2').text() 
      item['price'] = value.xpath('p[contains(@class, "ad-price")]').text() 
      yield item 

Artikel Modell

import scrapy 


class Product(scrapy.Item): 
    name = scrapy.Field() 
    price = scrapy.Field() 
    picture_url = scrapy.Field() 
    published_date = scrapy.Field(serializer=str) 

nach Scrapy Architektur, werden Elemente in die Item Pipeline (https://doc.scrapy.org/en/1.2/topics/item-pipeline.html) zurückgeführt werden, die verwendet wird, um die Daten zu speichern, DB/Speichern in Dateien und so weiter.

Ich bin jedoch mit der Frage fest - wie kann ich die Scraped Items Liste durch die Django REST APIview zurückgeben?

Erwartetes Verwendungsbeispiel:

from rest_framework.views import APIView 
from rest_framework.response import Response 

from .service.mysite_spider import MysiteSpider 

    class AggregatorView(APIView): 
     mysite_spider = MysiteSpider() 

     def get(self, request, *args, **kwargs): 

      self.mysite_spider.parse() 

      return Response('good') 
+0

Django Die Daten der REST API View sollten von * http request * stammen, nicht direkt von scrapy Sie sollten scrapy Element in db oder Datei speichern, welche django lesen kann, wenn eine Anfrage kommt. – Mil0R3

+0

Warum muss es von "Anfrage" kommen? Warum kann ich nicht einfach eine Logik im Controller verwenden? Ich habe das Thema jetzt aktualisiert, um zu zeigen, was ich meine. – user1935987

Antwort

2

ich nicht wirklich die Integration mit Django REST Framework testen habe, aber das folgende Snippet Sie erlauben würde, eine Spinne aus einem Python-Skript ausgeführt werden sollen, die daraus resultierenden Produkte zu sammeln um sie später zu behandeln.

from scrapy import signals 
from scrapy.crawler import Crawler, CrawlerProcess 
from ... import MysiteSpider 

items = [] 
def collect_items(item, response, spider): 
    items.append(item) 

crawler = Crawler(MysiteSpider) 
crawler.signals.connect(collect_items, signals.item_scraped) 

process = CrawlerProcess() 
process.crawl(crawler) 
process.start() # the script will block here until the crawling is finished 

# at this point, the "items" variable holds the scraped items 

Für die Aufzeichnung dies funktioniert, aber es könnte bessere Möglichkeiten, es zu tun :-)

Weiterführende Literatur:

+0

Gute Antwort, danke. Aber als ich so etwas versuchte, bekam ich einen folgenden Fehler: ValueError: Signal funktioniert nur im Haupt-Thread – BrottyS

Verwandte Themen