【问题标题】:QWebEngineView - loading of > 2mb contentQWebEngineView - 加载 > 2mb 的内容
【发布时间】:2018-08-02 06:39:20
【问题描述】:

因此,使用 PyQt5 的 QWebEngineView 以及 .setHTML 和 .setContent 方法有 2 MB 的大小限制。在谷歌上寻找解决方案时,我发现了两种方法:

使用 SimpleHTTPServer 提供文件。然而,这被公司使用的防火墙破坏了。

使用文件 URL 并指向本地文件。然而,这是一个相当糟糕的解决方案,因为 HTML 包含机密数据,在任何情况下我都不能将其留在硬盘上。

我目前看到的最佳解决方案是使用文件 url,并在程序退出/当 loadCompleted 报告完成时删除文件,以先到者为准。

但这不是一个很好的解决方案,我想问一下是否有一个我忽略的解决方案会更好?

【问题讨论】:

  • 你只需要打开一个动态端口(>=1024),这不应该被防火墙禁止。
  • 此外,2MB 限制仅记录在 setHtml 中,但不记录在 setContent 中。你真的尝试过 setContent 吗?
  • 记录了 setContent 的 2MB 限制,因为 setHTML 说它是 setContent 的简写。是的,我试过了,我得到了加载结果为“失败”的空白页面

标签: html qt pyqt5 qwebengineview


【解决方案1】:

为什么不通过自定义 url 方案处理程序加载/链接大部分内容?

webEngineView->page()->profile()->installUrlSchemeHandler("app", new UrlSchemeHandler(e));

class UrlSchemeHandler : public QWebEngineUrlSchemeHandler
{   Q_OBJECT
public:
    void requestStarted(QWebEngineUrlRequestJob *request) {
        QUrl url = request->requestUrl();
        QString filePath = url.path().mid(1);
        // get the data for this url
        QByteArray data = ..
        // 
        if (!data.isEmpty()) 
        {
            QMimeDatabase db;
            QString contentType = db.mimeTypeForFileNameAndData(filePath,data).name();
            QBuffer *buffer = new QBuffer();
            buffer->open(QIODevice::WriteOnly);
            buffer->write(data);
            buffer->close();
            connect(request, SIGNAL(destroyed()), buffer, SLOT(deleteLater()));
            request->reply(contentType.toUtf8(), buffer);
        } else {
            request->fail(QWebEngineUrlRequestJob::UrlNotFound);
        }
    }
};

然后您可以通过webEngineView->load(new QUrl("app://start.html")); 加载网站

内部的所有相对路径也将转发到您的 UrlSchemeHandler..

记得添加相应的包含

#include <QWebEngineUrlRequestJob>
#include <QWebEngineUrlSchemeHandler>
#include <QBuffer>

【讨论】:

  • Mh.我不知道如何在 PyQt5 中做到这一点,但这看起来值得研究。
  • @Berserker。我在 pyqt5 中试了一下,可以确认它按预期工作。
  • qutebrowser中有一个例子。好像解决了缓冲区的生命周期issue
  • 我在我的环境中使用它,它确实超过了 2MB 限制并直接提取数据。谢谢!。
  • 得收回一点,unicode 不工作 - 我用 "job.reply("text/html".encode(), buf)" 回应,而 buf 是一个 QIODevice,它包含 utf8 -string.encode()。但是,结果却破坏了编码;例如,“ä”变成“ä”。
【解决方案2】:

解决此问题的一种方法是使用requests 和QWebEnginePage 的方法runJavaScript

web_engine = QWebEngineView()
web_page = web_engine.page()
web_page.setHtml('')

url = 'https://youtube.com'
page_content = requests.get(url).text

# document.write writes a string of text to a document stream
# https://developer.mozilla.org/en-US/docs/Web/API/Document/write
# And backtick symbol(``) is for multiline strings
web_page.runJavaScript('document.write(`{}`);'.format(page_content))

【讨论】:

    猜你喜欢
    • 2019-12-07
    • 1970-01-01
    • 2022-11-05
    • 2018-12-07
    • 1970-01-01
    • 2019-11-27
    • 1970-01-01
    • 1970-01-01
    • 2020-12-18
    相关资源
    最近更新 更多