Python Django Scrapy如何将item返回给控制器?

3
我需要进行一些短时实时的爬虫,并在我的Django REST控制器中返回结果数据。 尝试使用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架构,items将被返回到Item Pipeline(https://doc.scrapy.org/en/1.2/topics/item-pipeline.html),用于存储数据到DB/保存到文件等。
然而,我遇到了一个问题——如何通过Django REST APIview返回已抓取的items列表?
期望的使用示例:
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')

Django REST API视图的数据应该来自http请求,而不是直接从scrapy获取,因此您应该将scrapy项目保存到数据库或文件中,当请求到来时,Django可以从中读取。 - Mil0R3
为什么必须从“request”中获取?我为什么不能在控制器内部使用一些逻辑来处理?我现在更新了主题以显示我的意思。 - user1935987
1个回答

3
我实际上没有测试与Django REST框架的集成,但以下代码片段将允许您从Python脚本运行Spider,收集结果项以便稍后处理。
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 

记录一下,这个方法是有效的,但可能有更好的方法来实现它 :-)

更多阅读:


1
好的答案,谢谢。但当我尝试类似的东西时,出现了以下错误:ValueError: 信号只在主线程中起作用。 - BrottyS

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接