QWebEngineView - загрузка ›2-мегабайтного содержимого

Таким образом, использование QWebEngineView PyQt5 и методов .setHTML и .setContent имеет ограничение на размер 2 МБ. При поиске решений по этому поводу я нашел два метода:

Используйте SimpleHTTPServer для обслуживания файла. Однако это блокируется брандмауэром, используемым в компании.

Используйте URL-адреса файлов и укажите на локальные файлы. Однако это довольно плохое решение, поскольку HTML содержит конфиденциальные данные, и я не могу оставить его на жестком диске ни при каких обстоятельствах.

Лучшее решение, которое я сейчас вижу, - использовать URL-адреса файлов и избавляться от файла при выходе из программы / когда loadCompleted сообщает, что это сделано, в зависимости от того, что наступит раньше.

Однако это не лучшее решение, и я хотел спросить, есть ли решение, которое я упускаю из виду, которое было бы лучше?


person Berserker    schedule 22.02.2018    source источник
comment
Вам просто нужно открыть динамический порт (›= 1024), это не должно быть запрещено брандмауэром.   -  person SteakOverflow    schedule 22.02.2018
comment
Также ограничение в 2 МБ задокументировано только для setHtml, но не для setContent. Вы действительно пробовали setContent?   -  person SteakOverflow    schedule 22.02.2018
comment
Ограничение 2 МБ задокументировано для setContent, поскольку setHTML говорит, что это сокращение для setContent. И да, я попробовал и получаю пустую страницу с результатом загрузки = не удалось   -  person Berserker    schedule 22.02.2018


Ответы (2)


Почему вы не загружаете / не связываете большую часть контента с помощью специального обработчика схемы 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>
person Johannes Munk    schedule 22.02.2018
comment
Mh. Я не знаю, как это сделать в PyQt5, но, похоже, стоит изучить этот вопрос. - person Berserker; 22.02.2018
comment
@Berserker. Я попробовал это в pyqt5 и могу подтвердить, что он работает должным образом. - person ekhumoro; 22.02.2018
comment
Пример есть в qutebrowser. Похоже, это решает проблему буфера за время существования буфера. - person Johannes Munk; 23.02.2018
comment
У меня это работает в моей среде, оно превышает ограничение в 2 МБ и напрямую извлекает данные. Спасибо!. - person Berserker; 23.02.2018
comment
Придется немного отступить, юникод не работает - я отвечаю с помощью job.reply (text / html.encode (), buf), а buf - это QIODevice, который содержит utf8-string.encode (). Однако в результате получилось разбитое кодирование; ä становится, например, ä. - person Berserker; 23.02.2018
comment
И все заработало. Хотя это немного сбивает с толку. Мне пришлось определить ‹meta charset = UTF-8›, в котором я не нуждался до перехода на эту систему, но теперь он работает. - person Berserker; 23.02.2018

Один из способов обойти это - использовать 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))
person avram    schedule 21.09.2018