如何在QWebEngineView中保存动态生成的网页?

3

我正在将一个网页加载到QWebEngineView上。用户创建不同类型的表格(报告),然后需要将这些表格作为网页保存到本地计算机。以下是我尝试过的方法:

  1. Here I use a QWebEnginePage::save() method, but nothing happens:

    connect(saveButton, &QPushButton::clicked, this, [this]()
    {
       engineWebView->page()->save("save.html");
    });
    
  2. Then I tried a QWebEngineProfile::download() method:

    connect(saveButton, &QPushButton::clicked, this, [this]()
    {
        engineWebView->page()->download(engineWebView->page()->url(), "save");
    });
    connect(engineWebView->page()->profile(), &QWebEngineProfile::downloadRequested, this, [this](QWebEngineDownloadItem *download) 
    {
        download->setPath("save.html");
        download->accept();
    });

在第二种解决方案中,我只能保存第一个加载的网页。没有动态创建的内容。
如何保存动态创建的数据?
编辑:最小可重现代码:
#include <QApplication>
#include <QDebug>
#include <QFile>
#include <QHBoxLayout>
#include <QPushButton>
#include <QWebEngineProfile>
#include <QWebEngineView>

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    QWebEngineView *engine = new QWebEngineView;
    QObject::connect(engine->page()->profile(), &QWebEngineProfile::downloadRequested, [](QWebEngineDownloadItem *download) {
        download->setPath("download.html");
        download->accept();
    });

    QPushButton *saveButton = new QPushButton("Save");
    QObject::connect(saveButton, &QPushButton::clicked, [engine]()
    {
        engine->page()->save("save.html");
    });

    QPushButton *toHtmlButton = new QPushButton("ToHtml");
    QObject::connect(toHtmlButton, &QPushButton::clicked, [engine]()
    {
        engine->page()->toHtml([](QString html){
        QFile file("toHtml.html");
        if (file.open(QFile::WriteOnly | QFile::Text))
        {
            QTextStream stream(&file);
            stream << html;
            file.waitForBytesWritten(-1);
            file.close();
        }
        else
            qDebug() << "Cannot create a file";
        });
    });

    QPushButton *downloadButton = new QPushButton("Download");
    QObject::connect(downloadButton, &QPushButton::clicked, [engine]()
    {
        engine->page()->download(engine->page()->url());
    });

    QHBoxLayout *hLyt = new QHBoxLayout;
    hLyt->addWidget(saveButton);
    hLyt->addWidget(toHtmlButton);
    hLyt->addWidget(downloadButton);

    QVBoxLayout *vLyt = new QVBoxLayout;
    vLyt->addLayout(hLyt);
    vLyt->addWidget(engine);

    QWidget *mainWin = new QWidget;
    mainWin->setLayout(vLyt);
    mainWin->show();

    // The url is an example for react usage. I am generating data using ReactJS that's why I use this example. What I need is to store the exact view of the dynamically generated calculator        
    engine->load(QUrl("https://ahfarmer.github.io/calculator/"));

    return app.exec();
}

“动态创建”的概念是主观的,如果您可以使用您提供的URL展示实际结果(HTML)和期望结果(HTML),那将很好。另一方面, HTML报告通常允许您以特定格式(如CSV、PDF、XLSX等)下载/导出文件。您的报告系统是否支持该功能呢? - eyllanesc
@eyllanesc 这就是问题所在。我们的报告系统只是使用标签(<table>,<tr>等)生成HTML表格。 - Bobur
@eyllanesc 请在Chrome中打开该URL。如果您查看页面源代码(Ctrl+U),它只包含调用JS函数的一行。但是,如果您检查一些DOM元素(Ctrs+Shift+I),它会向您显示“动态生成”的数据(大量HTML代码)。我需要确切的那段代码。 - Bobur
1个回答

4
如果您想获取动态生成的HTML,可以使用JavaScript通过QWebEnginePageouterHTML方法获取文档的外部HTML。请注意,该方法需要使用runJavaScript()方法运行JavaScript代码。
#include <QtWebEngineWidgets>

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    QWebEngineView *view = new QWebEngineView;
    QPushButton *button = new QPushButton("Press me");
    button->setEnabled(false);
    QObject::connect(button, &QPushButton::clicked, [view]()
    {
        view->page()->runJavaScript("document.documentElement.outerHTML", [](const QVariant &v) { 
            QFile file("outerHTML.html");
            if(!file.open(QFile::WriteOnly | QFile::Text)){
                qDebug() << "Cannot create a file";
                return;
            }
            QTextStream stream(&file);
            stream << v.toString();
            file.close();
        });
    });
    QObject::connect(view, &QWebEngineView::loadFinished, [button](bool ok){
        button->setEnabled(ok);
    });
    view->load(QUrl("https://ahfarmer.github.io/calculator/"));
    QWidget w;
    QVBoxLayout *lay = new QVBoxLayout(&w);
    lay->addWidget(button);
    lay->addWidget(view);
    w.resize(640, 480);
    w.show();
    return app.exec();
}

你能否评论一下为什么问题中提出的方法似乎不起作用? - Trilarion
@Trilarion,问题在于动态网页中有多个HTML。在之前的方法中,它们专注于从服务器下载的HTML,因此我认为Qt WebEngine的开发人员认为这些方法只提供了该信息,但他们也给了我们更多自由,因为我们可以使用JavaScript与DOM进行交互。 - eyllanesc
@Trilarion 总之,HTML的概念取决于你的分析角度。 - eyllanesc

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接