在Django视图中获取抓取结果

时间:2018-09-02 23:32:54

标签: django scrapy

我成功地抓取了一个页面,该页面返回了一个独特的商品。我既不想将报废的项目保存在数据库中也不保存到文件中。我需要在Django视图中获取它。

我的看法如下:

def start_crawl(process_number, court):
    """
    Starts the crawler.

        Args:
            process_number (str): Process number to be found.
            court (str): Court of the process.
    """
    runner = CrawlerRunner(get_project_settings())
    results = list()

    def crawler_results(sender, parse_result, **kwargs):
        results.append(parse_result)

    dispatcher.connect(crawler_results, signal=signals.item_passed)
    process_info = runner.crawl(MySpider, process_number=process_number, court=court)

    return results

我遵循了this解决方案,但结果列表始终为空。

我读到一些东西,如创建自定义中间件并通过process_spider_output方法获取结果。

如何获得所需的结果?

谢谢!

2 个答案:

答案 0 :(得分:1)

我设法在我的一个项目中实现了类似的功能。这是一个小型项目,我一直在寻找一种快速的解决方案。如果您将其放在生产环境中,则可能需要对其进行修改或支持多线程等。

概述

我创建了一个ItemPipeline,仅将项目添加到InMemoryItemStore助手中。然后,在我的__main__代码中,我等待搜寻器完成,然后从InMemoryItemStore中弹出所有项目。然后我可以根据需要操纵这些项目。

代码

items_store.py

Hacky内存存储。它不是很优雅,但是为我完成了工作。如果您愿意,请进行修改和改进。我已经将其实现为一个简单的类对象,因此我可以简单地将其导入项目中的任何位置并使用它,而无需传递其实例。

class InMemoryItemStore(object):
    __ITEM_STORE = None

    @classmethod
    def pop_items(cls):
        items = cls.__ITEM_STORE or []
        cls.__ITEM_STORE = None
        return items

    @classmethod
    def add_item(cls, item):
        if not cls.__ITEM_STORE:
            cls.__ITEM_STORE = []
        cls.__ITEM_STORE.append(item)

pipelines.py

此pipleline将从上面的代码片段中将对象存储在内存中。仅退回所有项目以保持常规管道流完整无缺。如果您不想将某些项目向下传递到其他管道,只需更改process_item即可不返回所有项目。

from <your-project>.items_store import InMemoryItemStore


class StoreInMemoryPipeline(object):
    """Add items to the in-memory item store."""
    def process_item(self, item, spider):
        InMemoryItemStore.add_item(item)
        return item

settings.py

现在在草稿器设置中添加StoreInMemoryPipeline。如果您更改了上面的process_item方法,请确保在此处设置适当的优先级(在此处将100改为100)。

ITEM_PIPELINES = {
   ...
   '<your-project-name>.pipelines.StoreInMemoryPipeline': 100,
   ...
}

main.py

在这里,我将所有这些东西绑在一起。我清理内存中的存储,运行搜寻器,并获取所有项目。

from scrapy.crawler import CrawlerProcess
from scrapy.utils.project import get_project_settings

from <your-project>.items_store import InMemoryItemStore
from <your-project>.spiders.your_spider import YourSpider

def get_crawler_items(**kwargs):
    InMemoryItemStore.pop_items()

    process = CrawlerProcess(get_project_settings())
    process.crawl(YourSpider, **kwargs)
    process.start()  # the script will block here until the crawling is finished
    process.stop()
    return InMemoryItemStore.pop_items()

if __name__ == "__main__":
    items = get_crawler_items()

答案 1 :(得分:0)

如果您真的想收集“特殊”对象中的所有数据。 将数据存储在单独的管道中,例如https://doc.scrapy.org/en/latest/topics/item-pipeline.html#duplicates-filter,并在close_spider(https://doc.scrapy.org/en/latest/topics/item-pipeline.html?highlight=close_spider#close_spider)中打开django对象。