2016-12-30 62 views
2

我需要做一些短的实时刮取并返回在我的Django REST控制器中产生的数据。python django scrapy返回项目到控制器

试图利用scrapy:

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 

项模型

import scrapy 


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

根据Scrapy架构,项目将被返回到Item Pipelinehttps://doc.scrapy.org/en/1.2/topics/item-pipeline.html),其用于存储所述数据到DB /保存到文件等等。

但是我坚持这个问题 - 我怎样才能通过Django REST APIview返回抓取的物品清单?

预期使用例如:

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 REST API视图的数据应该来自* http请求*,而不是直接来自scrapy,所以您应该将scrapy项目保存到数据库或文件,当请求到来时,django可以读取它。 – Mil0R3

+0

为什么它必须来自'request'?为什么我不能在控制器中使用一些逻辑? 我现在更新了这个话题来展示我的意思。 – user1935987

回答

2

我没有实际测试Django的REST框架的整合,但下面的代码片段将允许您从python脚本运行一个蜘蛛,收集所得项目稍后处理它们。

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 

根据记录,这工作,但可能有更好的方式来做到这一点:-)

延伸阅读:

+0

很好的答案,谢谢。但是当我尝试这样的事情时,我得到了以下错误:ValueError:signal只能在主线程中使用 – BrottyS