将scrapy日志输出流式传输到websocket

时间:2015-11-27 14:55:45

标签: python websocket scrapy twisted

我正在尝试构建一个API,当通过websocket消息请求时,它将运行Scrapy Web蜘蛛。

我想将日志记录输出转发到websocket客户端,这样您就可以看到 - 有时是长时间运行的 - 进程中发生了什么。完成后,我也会发送删除的结果。

由于可以在进程中运行Scrapy,我想这样做。我发现了一个解决方案,可以将外部进程流式传输到websocket,但如果可以在服务器中运行Scrapy,那么这似乎不正确。

https://tomforb.es/displaying-a-processes-output-on-a-web-page-with-websockets-and-python

有两种方法可以让我在Twisted中使用它:以某种方式使用LogObserver,或者定义一个LogHandler(可能是带有StringIO的StreamHandler),然后在Twisted中使用autobahn.websocket类(如WebSocketServerProtocol)以某种方式处理Stream。

现在我陷入困境,不知道如何连接两端。

有人可以提供一个简短的例子,说明如何将扭曲日志记录输出(尽可能避免文件)传输到websocket客户端吗?

1 个答案:

答案 0 :(得分:4)

我设法以某种方式解决了这个问题,并想让你知道我是怎么做到的:

基本思想是让一个进程远程调用并将流日志输出到客户端,通常是浏览器。

我自己决定使用autobahn.wscrossbar.io,而不是自己构建所有讨厌的细节,通过Wamp protocol提供pubsub和rpc,这实际上只是websockets上的JSON - 恰好是什么我本来打算建造,更方便!

这是一个非常基本的例子:

from twisted.internet.defer import inlineCallbacks

from autobahn.twisted.wamp import ApplicationSession
from example.spiders.basic_spider import BasicSpider
from scrapy.crawler import CrawlerRunner
from scrapy.utils.log import configure_logging
from scrapy.utils.project import get_project_settings

import logging

class PublishLogToSessionHandler(logging.Handler):
        def __init__(self, session, channel):
            logging.Handler.__init__(self)
            self.session = session
            self.channel = channel

        def emit(self, record):
            self.session.publish(self.channel, record.getMessage())

    class AppSession(ApplicationSession):

        configure_logging(install_root_handler=False)

        @inlineCallbacks
        def onJoin(self, details):
            logging.root.addHandler(PublishLogToSessionHandler(self, 'com.example.crawler.log'))

            # REGISTER a procedure for remote calling
            def crawl(domain):
                runner = CrawlerRunner(get_project_settings())
                runner.crawl("basic", domain=domain)
                return "Running..."

            yield self.register(crawl, 'com.example.crawler.crawl')