2

我正在使用 Qt 5.5.1,我使用 QWebview 制作了一个小型浏览器,当
我打开网页并按下按钮时,它会获取网站的内容,就像我在 QnetworkAccessManager 中使用 get 方法一样,而不使用它,因为我想要从具有登录页面的网站获取数据,因此当我登录时 URL 不会更改,并且没有将方法发布到 PHP 以获取数据。
例如,当我登录 www.login.com 时,登录数据显示在 同一链接
上该网站并通过按在Firefox中查看源代码从中获取数据登录数据出现在源代码中 这是我尝试过的



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" />

并且它对另一个字段具有相同的代码。
我在 Qt 中用于发帖的代码

manager = new QNetworkAccessManager(this);
QUrlQuery query;
query.addQueryItem("UserName", "AAAA");
query.addQueryItem("Password", "BBB");
reply = manager->post(QNetworkRequest(QUrl(ui->lineEdit->text().trimmed())), query.toString().toUtf8());
connect(reply,&QNetworkReply::downloadProgress,this,&MainWindow::progress);
connect(reply,SIGNAL(readyRead()),this,SLOT(readyRead()));
connect(reply, SIGNAL(finished()), this,SLOT(finish()));

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

4

1 回答 1

1

我将使用不同的方法,而不是模拟 POST 请求,我将正常加载登录页面QWebView并使用 Qt 填写用户名、密码并在提交按钮上进行虚假点击。

关于如何保存登录后的页面,而不是 HTML 代码,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"
}
于 2017-02-15T05:29:11.560 回答