我成功地抓取了一个页面,该页面返回了一个独特的商品。我既不想将报废的项目保存在数据库中也不保存到文件中。我需要在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方法获取结果。
如何获得所需的结果?
谢谢!
答案 0 :(得分:1)
我设法在我的一个项目中实现了类似的功能。这是一个小型项目,我一直在寻找一种快速的解决方案。如果您将其放在生产环境中,则可能需要对其进行修改或支持多线程等。
我创建了一个ItemPipeline
,仅将项目添加到InMemoryItemStore
助手中。然后,在我的__main__
代码中,我等待搜寻器完成,然后从InMemoryItemStore
中弹出所有项目。然后我可以根据需要操纵这些项目。
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)
此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
现在在草稿器设置中添加StoreInMemoryPipeline
。如果您更改了上面的process_item
方法,请确保在此处设置适当的优先级(在此处将100改为100)。
ITEM_PIPELINES = {
...
'<your-project-name>.pipelines.StoreInMemoryPipeline': 100,
...
}
在这里,我将所有这些东西绑在一起。我清理内存中的存储,运行搜寻器,并获取所有项目。
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对象。