Qt WebView - intercept loading of JS/CSS Libraries to load local ones

£可爱£侵袭症+ 提交于 2019-12-04 05:53:50

The following example shows how I've done it. It uses the QWebEngineUrlRequestInterceptor to redirect content to a local server.

As an example, I intercept the stacks.css for stackoverflow and make an obvious change.

import requests
import sys
import threading
from PyQt5 import QtWidgets, QtCore
from PyQt5.QtWebEngineWidgets import QWebEngineView, QWebEnginePage, QWebEngineProfile
from PyQt5.QtWebEngineCore import QWebEngineUrlRequestInterceptor, QWebEngineUrlRequestInfo
from http.server import HTTPServer, SimpleHTTPRequestHandler
from socketserver import ThreadingMixIn

# Set these to the address you want your local patch server to run
HOST = '127.0.0.1'
PORT = 1235

class WebEngineUrlRequestInterceptor(QWebEngineUrlRequestInterceptor):
    def patch_css(self, url):
        print('patching', url)
        r = requests.get(url)
        new_css = r.text + '#mainbar {background-color: cyan;}'  # Example of some css change
        with open('local_stacks.css', 'w') as outfile:
            outfile.write(new_css)
    def interceptRequest(self, info: QWebEngineUrlRequestInfo):
        url = info.requestUrl().url()
        if url == "https://cdn.sstatic.net/Shared/stacks.css?v=596945d5421b":
            self.patch_css(url)
            print('Using local file for', url)
            info.redirect(QtCore.QUrl('http:{}:{}/local_stacks.css'.format(HOST, PORT)))

class ThreadingHTTPServer(ThreadingMixIn, HTTPServer):
    """Threaded HTTPServer"""

app = QtWidgets.QApplication(sys.argv)

# Start up thread to server patched content
server = ThreadingHTTPServer((HOST, PORT), SimpleHTTPRequestHandler)
server_thread = threading.Thread(target=server.serve_forever)
server_thread.daemon = True
server_thread.start()

# Install an interceptor to redirect to patched content
interceptor = WebEngineUrlRequestInterceptor()
profile = QWebEngineProfile.defaultProfile()
profile.setRequestInterceptor(interceptor)

w = QWebEngineView()
w.load(QtCore.QUrl('https://stackoverflow.com'))
w.show()
app.exec_()

So, the solution I went with in the end was, first, introduce jinja templates. Then, using those the template would have variables and blocks set based on export or internal use and from there I did not need the interceptor anymore.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!