gpt4 book ai didi

python - QtWebEngine 拦截带有自定义 URL 模式服务回复的请求

转载 作者:行者123 更新时间:2023-12-05 05:05:21 38 4
gpt4 key购买 nike

我正在尝试使用自定义 URL 方案重写多个 HTTP 请求:
所有请求 http://static.foo.bar应该改写为static://...并提供一些回复。

问题:
拦截和重定向似乎有效,但无论我对 QWebEngineUrlSchemeHandler 的实现如何返回(图像或 html)总是替换完整的 HTML 页面。

预期结果:
示例图像 /tmp/iphone.jpg服务于 SchemeHandler嵌入在 HTML 页面中,因此 HTML 显示 <h1>标题和 2 张图片。

版本:
Python 3.7.4
PyQt:5.14.1

示例代码:

import sys
import signal
from PyQt5 import QtCore
from PyQt5.QtCore import QUrl, QObject
from PyQt5.QtWebEngineWidgets import QWebEngineView, QWebEngineSettings, QWebEnginePage, QWebEngineProfile
from PyQt5.QtWebEngineCore import QWebEngineUrlRequestInterceptor, QWebEngineUrlSchemeHandler, QWebEngineUrlScheme
from PyQt5.QtWidgets import QApplication, QMainWindow


class WebEngineUrlRequestInterceptor(QWebEngineUrlRequestInterceptor):
# Everything requested from static.foo.bar goes to static://
# //static.foo.bar/1/2/4.jpeg >> static://1/2/4.jpeg
def interceptRequest(self, info):
print("interceptRequest")
print(info.requestUrl())
if 'static.foo.bar' in str(info.requestUrl()):
url = QUrl()
url.setScheme(MyWebEngineUrlScheme.scheme.decode())
url.setHost('baz.jpg')
print('Intercepting and redirecting to: %s' % url)
info.redirect(url)


class MyWebEnginePage(QWebEnginePage):
# debugging
def acceptNavigationRequest(self, url, _type, isMainFrame):
print("acceptNavigationRequest: %s" % url)
return QWebEnginePage.acceptNavigationRequest(self, url, _type, isMainFrame)


class SchemeHandler(QWebEngineUrlSchemeHandler):
def __init__(self, app):
super().__init__(app)

def requestStarted(self, request):
url = request.requestUrl()
print('SchemeHandler requestStarted: %s' % url)

# Returns a sample image
raw_html = open('/tmp/iphone.jpg', 'rb').read()
buf = QtCore.QBuffer(parent=self)
request.destroyed.connect(buf.deleteLater)
buf.open(QtCore.QIODevice.WriteOnly)
buf.write(raw_html)
buf.seek(0)
buf.close()
request.reply(b"image/jpeg", buf)
return


class MyWebEngineUrlScheme(QObject):
# Register scheme
scheme = b"static"

def __init__(self, parent=None):
super().__init__(parent)
scheme = QWebEngineUrlScheme(MyWebEngineUrlScheme.scheme)
QWebEngineUrlScheme.registerScheme(scheme)
self.m_functions = dict()

def init_handler(self, profile=None):
if profile is None:
profile = QWebEngineProfile.defaultProfile()
handler = profile.urlSchemeHandler(MyWebEngineUrlScheme.scheme)
if handler is not None:
profile.removeUrlSchemeHandler(handler)

self.handler = SchemeHandler(self)
print("registering %s to %s" % (MyWebEngineUrlScheme.scheme, self.handler))
profile.installUrlSchemeHandler(MyWebEngineUrlScheme.scheme, self.handler)


schemeApp = MyWebEngineUrlScheme()
signal.signal(signal.SIGINT, signal.SIG_DFL)
app = QApplication(sys.argv)
win = QMainWindow()
win.resize(800, 600)

html = """
<html>
<body>
<h1>test</h1>
<hr>
<p>First image</p>
<img src="http://static.foo.bar/baz.jpg" />
<hr>
<p>Second image</p>
<img src="https://store.storeimages.cdn-apple.com/4668/as-images.apple.com/is/iphone-xr-red-select-201809?wid=1200&hei=630&fmt=jpeg&qlt=95&op_usm=0.5,0.5&.v=1551226038669" />
</body>
</html>
"""

browser = QWebEngineView()
interceptor = WebEngineUrlRequestInterceptor()
profile = QWebEngineProfile()
profile.setUrlRequestInterceptor(interceptor)
page = MyWebEnginePage(profile, browser)
schemeApp.init_handler(profile)

browser.settings().setAttribute(QWebEngineSettings.PluginsEnabled, True)
browser.settings().setAttribute(QWebEngineSettings.JavascriptCanOpenWindows, False)
browser.settings().setAttribute(QWebEngineSettings.LinksIncludedInFocusChain, False)
browser.settings().setAttribute(QWebEngineSettings.LocalStorageEnabled, True)
browser.settings().setAttribute(QWebEngineSettings.JavascriptEnabled, True)

page.setHtml(html)
browser.setPage(page)
browser.show()

win.setCentralWidget(browser)
win.show()

sys.exit(app.exec_())

最佳答案

如果您分析页面请求的 url,您会得到:

PyQt5.QtCore.QUrl('data:text/html;charset=UTF-8,%0A%3Chtml%3E%0A%3Cbody%3E%0A%3Ch1%3Etest%3C%2Fh1%3E%0A%3Chr%3E%0A%3Cp%3EFirst image%3C%2Fp%3E%0A%3Cimg src%3D%22http%3A%2F%2F<b>static.foo.bar</b>%2Fbaz.jpg%22 %2F%3E%0A%3Chr%3E%0A%3Cp%3ESecond image%3C%2Fp%3E%0A%3Cimg src%3D%22https%3A%2F%2Fstore.storeimages.cdn-apple.com%2F4668%2Fas-images.apple.com%2Fis%2Fiphone-xr-red-select-201809%3Fwid%3D1200%26hei%3D630%26fmt%3Djpeg%26qlt%3D95%26op_usm%3D0.5%2C0.5%26.v%3D1551226038669%22 %2F%3E%0A%3C%2Fbody%3E%0A%3C%2Fhtml%3E%0A')
PyQt5.QtCore.QUrl('http://<b>static.foo.bar</b>/baz.jpg')
PyQt5.QtCore.QUrl('https://store.storeimages.cdn-apple.com/4668/as-images.apple.com/is/iphone-xr-red-select-201809?wid=1200&hei=630&fmt=jpeg&qlt=95&op_usm=0.5,0.5&.v=1551226038669')

条件 if 'static.foo.bar' in str(info.requestUrl()): 满足第一个和第二个 url((为了更好的可视化,我将其标记为粗体).

解决办法是改进过滤器:

class WebEngineUrlRequestInterceptor(QWebEngineUrlRequestInterceptor):
# Everything requested from static.foo.bar goes to static://
# //static.foo.bar/1/2/4.jpeg >> static://1/2/4.jpeg
def interceptRequest(self, info):
print("interceptRequest")
print(info.requestUrl())
if info.requestUrl().host().startswith("static.foo.bar"): # or if info.requestUrl().host() == "static.foo.bar":
url = QUrl()
url.setScheme(MyWebEngineUrlScheme.scheme.decode())
url.setHost(info.requestUrl().path()[1:]) # remove "/"
print("Intercepting and redirecting to: %s" % url)
info.redirect(url)

关于python - QtWebEngine 拦截带有自定义 URL 模式服务回复的请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60591722/

38 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com