我正在尝试构建一个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客户端吗?
答案 0 :(得分:4)
我设法以某种方式解决了这个问题,并想让你知道我是怎么做到的:
基本思想是让一个进程远程调用并将流日志输出到客户端,通常是浏览器。
我自己决定使用autobahn.ws和crossbar.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')