简体   繁体   English

如何保持python qtwebkit实例运行和持久化?

[英]How to keep python qtwebkit instance running and persistent?

I need my Python QtWebKit script to stay running and listen for further commands. 我需要我的Python QtWebKit脚本保持运行并监听其他命令。 Right now, if a user connects and sends a command to the server, the server side script will just run and exit once completed. 现在,如果用户连接并向服务器发送命令,则服务器端脚本将在完成后立即运行并退出。

For example, if the user enters in a URL to navigate to, QtWebKit fetches the URL and renders it. 例如,如果用户输入URL进行导航,则QtWebKit将获取URL并进行呈现。 At some point down the road, they may wish to send a login command and view the screenshot of that page. 他们可能希望在某个时候发送登录命令并查看该页面的屏幕截图。 The script begins, navigates to the URL and logs in, and takes the screenshot of that page. 脚本开始,导航到URL并登录,然后获取该页面的屏幕截图。

Is there any way to keep the script to listen for future commands without having to start from the beginning? 有什么方法可以让脚本不必从头开始就可以监听未来的命令?

What is expected: User sends command to server, QtWebKit loads the URL and stays open. 预期结果:用户向服务器发送命令,QtWebKit加载URL并保持打开状态。 The user sends a command to login and take a screenshot, and QtWebKit logs in and takes a screenshot without having to relaunch the script. 用户发送命令登录并截取屏幕截图,而QtWebKit登录并截取屏幕截图,而无需重新启动脚本。

The special case here is that the user does not know ahead of time the exact sequence of commands he wishes to execute. 此处的特殊情况是用户不会提前知道他希望执行的命令的确切顺序。 So the user can't spell out A to Z and have the script run through it all at once. 因此,用户无法将A到Z拼写清楚并让脚本一次运行。

I used twisted to setup a simple xmlrpc server as backend, it's persistent and has the task to create new instances of PyQt/PySide based webkit browsers if needed, or to reuse existing ones. 我使用twisted将一个简单的xmlrpc服务器设置为后端,它是持久性的,并且有任务根据需要创建基于PyQt / PySide的Webkit浏览器的新实例,或者重用现有的浏览器。 A separate frontend webapp which is the "middle-man" between the user and the backend application sends the commands to the twisted xmlrpc server, along with a session_id, by which the twisted server can lookup if the session_id has an already running browser, or need to instantiate a new one. 一个单独的前端Web应用程序(即用户和后端应用程序之间的“中间人”)将命令与session_id一起发送到扭曲的xmlrpc服务器,如果session_id具有已运行的浏览器,则扭曲的服务器可以通过该查找服务器;或者需要实例化一个新的。 Here's a simple example: 这是一个简单的例子:

# -*- coding: utf-8 -*-
from pyvirtualdisplay import Display
display = Display(visible=False, size=(1024, 768), color_depth=24)
display.start()

from PySide.QtGui import QApplication
app = QApplication([])
import qt4reactor
qt4reactor.install()

from twisted.web import server
from twisted.web.xmlrpc import XMLRPC
from twisted.internet import defer
from PySide.QtWebKit import QWebView, QWebPage
from PySide.QtNetwork import QNetworkAccessManager, QNetworkRequest
from PySide.QtCore import QUrl, QByteArray


class Browser(object):

    def __init__(self):
        self.network_manager = QNetworkAccessManager()

        self.web_page = QWebPage()
        self.web_page.setNetworkAccessManager(self.network_manager)

        self.web_view = QWebView()
        self.web_view.setPage(self.web_page)
        self.web_view.loadFinished.connect(self._load_finished)

    def _load_finished(self, ok):
        # the page is loaded
        frame = self.web_view.page().mainFrame()
        self.deferred_request.callback(frame.toHtml())

    def _make_request(self, url):
        request = QNetworkRequest()
        request.setUrl(QUrl(url))
        return request

    def perform(self, request_data):
        # say request_data is a dict having keys: 'url', 'post_data'
        self.deferred_request = defer.Deferred()
        request = self._make_request(request_data['url'])
        self.web_view.load(request)

        return self.deferred_request


class TestXMLRPCServer(XMLRPC):

    def __init__(self):
        XMLRPC.__init__(self, allowNone=True)
        self.browser_instances = dict()

    def xmlrpc_open(self, request_data, session_id):
        print session_id, request_data
        try:
            browser = self.browser_instances[session_id]
            print 'using existing instance'
        except KeyError:
            browser = Browser()
            self.browser_instances[session_id] = browser
            print 'new instance created'

        return browser.perform(request_data)


def start_server(port=1234):
    from twisted.internet import reactor
    r = TestXMLRPCServer()
    reactor.listenTCP(port, server.Site(r))
    reactor.run()


if __name__ == '__main__':
    start_server()

And a client just to test the functionality: 而客户端只是为了测试功能:

# -*- coding: utf-8 -*-
import xmlrpclib

def test_server(port=1234):
    s = xmlrpclib.Server('http://localhost:{0}/'.format(port))
    session_id = 'a1b2c3d4e5f6'
    html = s.open({'url': 'http://www.google.com'}, session_id)
    print unicode(html).encode('utf-8')
    html = s.open({'url': 'http://www.ubuntu.com'}, session_id)
    print unicode(html).encode('utf-8')

    session_id = 'f6e5d4c3b2a1'
    html = s.open({'url': 'http://www.yahoo.com'}, session_id)
    print unicode(html).encode('utf-8')

if __name__ == '__main__':
    test_server()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM