Html 使用Qt5.5.1从QWebView获取网站内容

Html 使用Qt5.5.1从QWebView获取网站内容,html,c++,qt,qnetworkaccessmanager,qnetworkreply,Html,C++,Qt,Qnetworkaccessmanager,Qnetworkreply,我使用的是Qt 5.5.1,当我打开网页并按下按钮时,我使用我想要的QWebview制作了一个小浏览器,它像我在QnetworkAccessManager中使用get方法一样获取网站的内容,而不使用它,因为我希望从具有登录页面的网站获取数据,以便在我登录时URL不会更改,并且没有将方法发布到PHP以获取数据 例如,当我登录www.login.com时,登录数据显示在同一链接上 我需要知道我能不能解决这个问题,或者我是否能从QWebview中打开的网站获取当前数据 注意 当我登录到该网站并通过在f

我使用的是Qt 5.5.1,当我打开网页并按下按钮时,我使用我想要的QWebview制作了一个小浏览器,它像我在QnetworkAccessManager中使用get方法一样获取网站的内容,而不使用它,因为我希望从具有登录页面的网站获取数据,以便在我登录时URL不会更改,并且没有将方法发布到PHP以获取数据
例如,当我登录www.login.com时,登录数据显示在同一链接上
我需要知道我能不能解决这个问题,或者我是否能从QWebview中打开的网站获取当前数据
注意
当我登录到该网站并通过在firefox中按view source code从中获取数据时,登录数据将显示在源代码中
这就是我尝试的

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow) {
        ui->setupUi(this);
        ui->webView->load(QUrl("https://www.login.com")); // load page that have user name and password field
        QWebPage *page = ui->webView->page(); // get the current page 
        manager = page->networkAccessManager(); // get the access manager from this page
    }

    MainWindow::~MainWindow() {
        delete ui;
    }
    // get button
    void MainWindow::on_pushButton_clicked() {
        reply = manager->get(QNetworkRequest(QUrl("https://www.login.com"))); // make get now after login
        connect(reply, SIGNAL(readyRead()),this,SLOT(readyRead()));
        connect(reply, SIGNAL(finished()),this, SLOT(finish()));
    }

    void MainWindow::readyRead() {
        QString str = QString::fromUtf8(reply->readAll()).trimmed(); // read the data
        ui->plainTextEdit->appendPlainText(str);
    }
但是我没有登录就得到了第一页的数据。我想得到登录后的页面内容,请给我任何提示,我应该怎么做。
更新
我从firefox查看页面源代码获取文本输入名称,并使用QUrlQuery向其发布结果是第一个未登录的页面这部分HTML代码我获取了它的名称

<label class="label-off" for="dwfrm_ordersignup_orderNo">Numéro de la commande</label> <input class="textinput required" id="anyname" type="text"  name="UserName"  value=""  maxlength="2147483647" placeholder="* UserName" data-missing-error="Saisis ton numéro de commande. "  data-parse-error="Ce contenu est invalide"  data-range-error="Ce contenu est trop long ou trop court"  required="required" />

我用我制作的PHP页面尝试了post代码,它解决了这里的问题,它只是HTML页面

我将使用另一种方法,而不是模拟post请求,我将使用
QWebView
正常加载登录页面,并使用Qt填充用户名、密码,然后假点击提交按钮

关于如何保存登录后的页面,Qt提供的一个好方法是将web视图呈现为PDF格式,其缺点是丢失HTML代码

如果代码足够,您可以使用
webview->page()->mainFrame()->toHtml()

看一个简单的例子,请注意,您需要使代码适应您的环境,分析登录页面,等等

void MainWindow::start()
{
    connect(webview, &QWebView::loadFinished, this, &MainWindow::LogIn);

    QString html = "<html>"
                   "<body>"
                   "<form action=\"https://httpbin.org/post\" method=\"POST\">"
                   "Username:<br>"
                   "<input type=\"text\" name=\"usernameinput\" value=\"abc\">"
                   "<br>"
                   "Password:<br>"
                   "<input type=\"password\" name=\"passwordinput\" value=\"123\">"
                   "<br><br>"
                   "<button name=\"button1\">Submit</button>"
                   "</form>"
                   "</body>"
                   "</html>";

    webview->setHtml(html); //Load yours https://www.login.com, using setHtml just for example
}

void MainWindow::LogIn(bool ok)
{
    disconnect(webview, &QWebView::loadFinished, this, &MainWindow::LogIn); //Disconnect the SIGNAL

    if (!ok)
        return;

    QWebElement document = webview->page()->mainFrame()->documentElement();

    QWebElement username = document.findFirst("input[name=usernameinput]"); //Find the first input with name=usernameinput

    if (username.isNull())
        return;

    username.setAttribute("value", "def"); //Change the value of the usernameinput input even
                                           //if it already has some value

    QWebElement password = document.findFirst("input[name=passwordinput]"); //Do the same for password

    if (password.isNull())
        return;

    password.setAttribute("value", "123456"); //Do the same for password

    QWebElement button = document.findFirst("button[name=button1]"); //Find the button with name "button1"

    if (button.isNull())
        return;

    connect(webview, &QWebView::loadFinished, this, &MainWindow::finished);

    button.evaluateJavaScript("this.click()"); //Do a fake click on the submit button
}

void MainWindow::finished(bool ok)
{
    disconnect(webview, &QWebView::loadFinished, this, &MainWindow::finished);

    if (!ok)
        return;

    QByteArray data;
    QBuffer buffer(&data);

    if (!buffer.open(QIODevice::WriteOnly))
        return;

    QPdfWriter pdfwriter(&buffer);

    pdfwriter.setResolution(100); //In DPI

    webview->page()->setViewportSize(QSize(pdfwriter.width(), pdfwriter.height()));

    QPainter painter;
    painter.begin(&pdfwriter);
    webview->page()->mainFrame()->render(&painter);
    painter.end();

    buffer.close();

    qDebug() << "PDF Size:" << data.size(); //Now you have a PDF in memory stored on "data"
}
void主窗口::start()
{
连接(webview、&QWebView::loadFinished、this、&MainWindow::LogIn);
QString html=“”
""
""
“用户名:
” "" “
” “密码:
” "" “

” “提交” "" "" ""; webview->setHtml(html);//加载您的https://www.login.com,例如使用setHtml } void主窗口::登录(bool确定) { 断开连接(webview,&QWebView::loadFinished,this,&MainWindow::LogIn);//断开信号连接 如果(!ok) 返回; QWebElement document=webview->page()->mainFrame()->documentElement(); QWebElement username=document.findFirst(“输入[name=usernameinput]”;//查找名称为usernameinput的第一个输入 if(username.isNull()) 返回; username.setAttribute(“value”、“def”);//甚至更改usernameinput的值 //如果它已经有了一些价值 QWebElement password=document.findFirst(“输入[name=passwordinput]”;//对密码执行相同操作 if(password.isNull()) 返回; setAttribute(“value”,“123456”);//对password执行相同的操作 QWebElement button=document.findFirst(“button[name=button1]”;//查找名为“button1”的按钮 if(button.isNull()) 返回; 连接(webview、&QWebView::loadFinished、this、&MainWindow::finished); button.evaluateJavaScript(“this.click()”);//在提交按钮上进行假单击 } void主窗口::已完成(bool确定) { 断开连接(webview,&QWebView::loadFinished,this,&MainWindow::finished); 如果(!ok) 返回; QByteArray数据; QBuffer(和数据); 如果(!buffer.open(QIODevice::WriteOnly)) 返回; QPdfWriter pdfwriter(&buffer); pdfwriter.setResolution(100);//以DPI为单位 webview->page()->setViewportSize(QSize(pdfwriter.width(),pdfwriter.height()); 油漆工; 画师。开始(&pdfwriter); webview->page()->mainFrame()->渲染(&painter); 结束(); buffer.close();
qDebug()如果您可能希望向服务器发送post方法,则需要分析登录页面,查看文本输入的名称,并将其作为键传递给
QUrlQuery
,然后传递相应的值(通常是名称和密码)。发布了一个如何使用Qt执行post方法的示例。我用我尝试过的方法更新了问题。请查看此问题。请查看我的答案。非常感谢您的回复和您的努力。我对此表示感谢。我尝试了此代码,但它生成了一个pdf文件,其中包含登录页,其中包含写入的字段用户名和密码no cli按下ck按钮!我检查了源代码,发现submit按钮的类型不是,但我在代码中将其更改为“button[type=submit]”,而不是“input[type=submit]”在此之前,它给我的按钮是空的最后一件事,我尝试手动输入用户数据之后,从网页制作一个pdf文件,它的工作,并显示我的数据登录后,它的完美现在有任何方法,使按钮点击在代码中,你做了吗?可能是因为类型的提交没有,这是我应该改变任何在code或它是相同的逻辑?是的,这取决于对象,如果它的类型=提交,或者是按钮、超链接等。您需要在页面上找到对象的唯一标识符,并将其传递给
findFirst
。我编辑了我的答案,以显示按钮名称=button1的示例。
void MainWindow::start()
{
    connect(webview, &QWebView::loadFinished, this, &MainWindow::LogIn);

    QString html = "<html>"
                   "<body>"
                   "<form action=\"https://httpbin.org/post\" method=\"POST\">"
                   "Username:<br>"
                   "<input type=\"text\" name=\"usernameinput\" value=\"abc\">"
                   "<br>"
                   "Password:<br>"
                   "<input type=\"password\" name=\"passwordinput\" value=\"123\">"
                   "<br><br>"
                   "<button name=\"button1\">Submit</button>"
                   "</form>"
                   "</body>"
                   "</html>";

    webview->setHtml(html); //Load yours https://www.login.com, using setHtml just for example
}

void MainWindow::LogIn(bool ok)
{
    disconnect(webview, &QWebView::loadFinished, this, &MainWindow::LogIn); //Disconnect the SIGNAL

    if (!ok)
        return;

    QWebElement document = webview->page()->mainFrame()->documentElement();

    QWebElement username = document.findFirst("input[name=usernameinput]"); //Find the first input with name=usernameinput

    if (username.isNull())
        return;

    username.setAttribute("value", "def"); //Change the value of the usernameinput input even
                                           //if it already has some value

    QWebElement password = document.findFirst("input[name=passwordinput]"); //Do the same for password

    if (password.isNull())
        return;

    password.setAttribute("value", "123456"); //Do the same for password

    QWebElement button = document.findFirst("button[name=button1]"); //Find the button with name "button1"

    if (button.isNull())
        return;

    connect(webview, &QWebView::loadFinished, this, &MainWindow::finished);

    button.evaluateJavaScript("this.click()"); //Do a fake click on the submit button
}

void MainWindow::finished(bool ok)
{
    disconnect(webview, &QWebView::loadFinished, this, &MainWindow::finished);

    if (!ok)
        return;

    QByteArray data;
    QBuffer buffer(&data);

    if (!buffer.open(QIODevice::WriteOnly))
        return;

    QPdfWriter pdfwriter(&buffer);

    pdfwriter.setResolution(100); //In DPI

    webview->page()->setViewportSize(QSize(pdfwriter.width(), pdfwriter.height()));

    QPainter painter;
    painter.begin(&pdfwriter);
    webview->page()->mainFrame()->render(&painter);
    painter.end();

    buffer.close();

    qDebug() << "PDF Size:" << data.size(); //Now you have a PDF in memory stored on "data"
}