简体   繁体   English

QtWebKit - 用户脚本/Javascript 注入

[英]QtWebKit - Userscript/Javascript Injection

I've been doing testing work in Python using QtWebkit/Spynner.我一直在使用 QtWebkit/Spynner 在 Python 进行测试工作。 As QtWebKit has Javascript support just like Chrome's Webkit, is it possible to inject a userscript or a piece of javascript at the beginning of a page just like you would a regular user script in Chrome?由于 QtWebKit 像 Chrome 的 Webkit 一样支持 Javascript,是否可以像在 Chrome 中的常规用户脚本一样在页面开头注入用户脚本或一段 javascript?

Hopefully a simple question for those experience!希望这些经验的简单问题! Thanks in advance!提前致谢!

You can use the following approach:您可以使用以下方法:

  1. Register a handler forQWebPage.frameCreatedQWebPage.frameCreated注册一个处理器
  2. Inside that event handler, register a new event handler for QWebFrame.javaScriptWindowObjectCleared在该事件处理程序中,为QWebFrame.javaScriptWindowObjectCleared注册一个新的事件处理程序
  3. In that second event handler, use QWebFrame.evaluateJavaScript (or Spynner's runjs method) to run your Javascript.在第二个事件处理程序中,使用QWebFrame.evaluateJavaScript (或 Spynner 的runjs方法)运行您的 Javascript。

This is the approach taken by capybara-webkit to execute its utility scripts.这是capybara-webkit执行其实用程序脚本所采用的方法。 Unfortunately I can't give you example Python code because I'm not familiar with the Qt Python bindings.不幸的是,我不能给你示例 Python 代码,因为我不熟悉 Qt Python 绑定。

From the previous answer (Niklas B.): the capybara-webkit uses a not so useful double subscription of signal-slot (frameCreated-javaScriptWindowObjectCleared), and uses a sender() call in the injectJavascriptHelpers() function that is not a good practice for a decoupled code.从之前的回答(Niklas B.):capybara-webkit 使用了一个不太有用的信号槽双重订阅(frameCreated-javaScriptWindowObjectCleared),并在 injectJavascriptHelpers() function 中使用了 sender() 调用,这不是一个好习惯对于解耦代码。

Actually you only need to connect the "javaScriptWindowObjectCleared" signal from the mainFrame() to your slot.实际上,您只需要将来自 mainFrame() 的“javaScriptWindowObjectCleared”信号连接到您的插槽。

Supposing you are using the old Widget coding style for PyQt (no qml then):假设您正在为 PyQt 使用的 Widget 编码风格(那么没有 qml):

class InstrumentedPage(PyQt5.QtWebKitWidgets.QWebPage):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.loadFinished.connect(self.finished)
        self.mainFrame().javaScriptWindowObjectCleared.connect(self.initYourJavascriptAtTheBeginningHere)

    def javaScriptConsoleMessage(self, message, lineNumber, sourceID):
        message = "%s (%s:%d)" % (message, sourceID, lineNumber)
        self.__logger.info("JS :: %s" % message )

    def initYourJavascriptAtTheBeginningHere(self):
        js = "console.log(\"INITED\");"
        self.mainFrame().evaluateJavaScript(js)

    def injectYourJavascriptHere(self, js):
        return self.mainFrame().evaluateJavaScript(js)

    def finished(self, status):
        self.__logger.info("InstrumentedPage.finished() :: init status => %s" % status)

class MainWindow(PyQt5.QtWidgets.QWidget):

    def __init__(self, config, config_file_name, parent=None):
        super().__init__(parent)

        self.ui = Ui_MainWindow.Ui_MainWindow()
        self.ui.setupUi( self )

        self.web_page = InstrumentedPage()
        self.ui.webView.setPage(self.web_page)

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

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