1

QWebPage を使用していくつかの Web ページをスクレイピングするアプリケーションを作成しています。応答が Http リダイレクト (302、303 など) の場合、問題が発生します。QWebPage は単にリダイレクトに従いません。

この問題を回避するために、ページのネットワーク マネージャーの終了信号に接続して、応答のステータスを取得し、リダイレクトをロードしましたが、QWebPage で 2 回目にloadメソッドを呼び出すと、URL が次のように設定されます。空白で、リクエストは一切発行しません。

関連するコードの一部を次に示します。

connect(page->networkAccessManager(), SIGNAL(finished(QNetworkReply*)), SLOT(gotReply(QNetworkReply*)));
connect(page, SIGNAL(loadFinished(bool)), SLOT(doneLoading(bool)));
page->mainFrame()->load(url);

私のスロット:

void Snapshot::gotReply(QNetworkReply *reply)
{
    if(reply->header(QNetworkRequest::ContentTypeHeader).toString().contains(QString("text/html")))
    {
        qDebug() << "Got reply " + reply->url().toString() + " - " + reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toString() + " - " + reply->header(QNetworkRequest::ContentTypeHeader).toString();
    }

    if(!statusCode && reply->header(QNetworkRequest::ContentTypeHeader).toString().contains(QString("text/html"))) {
        statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
        redirectUrl = QUrl(reply->header(QNetworkRequest::LocationHeader).toUrl());
    }
}

void Snapshot::doneLoading(bool)
{
    // A reasonable waiting time for any script to execute
    timer->start(3000);
}

void Snapshot::doneWaiting()
{
    if( statusCode != 0 &&
        statusCode != 301 &&
        statusCode != 302 &&
        statusCode != 303
       ) {
        qDebug() << page->mainFrame()->url().toString();
        qDebug() << page->mainFrame()->toHtml();

        QImage image(page->viewportSize(), QImage::Format_ARGB32);
        QPainter painter(&image);

        page->mainFrame()->render(&painter);

        painter.end();

        image.save(*outputFilename);

        delete outputFilename;
        QApplication::quit();
    }
    else if(statusCode != 0) {
        statusCode = 0;
        qDebug() << "Redirecting to: " + redirectUrl.toString();
        if(page->mainFrame()->url().toString().isEmpty()) {
            qDebug() << "about:blank";
            page->mainFrame()->load(this->redirectUrl); // No network activity after this
            qDebug() << "Loading";
        }
    }

    // This should ensure that the program never hangs
    if(statusCode == 0) {
        if(tries > 5) {
            qDebug() << "Giving up.";
            QApplication::quit();
        }
        tries++;
    }
}
4

1 に答える 1

0

問題は、私がテストしていたページが https にリダイレクトされ、自己署名証明書を持っていたことです。

解決策は、QNetworkReply が ssl エラーを無視するようにすることでした。

void Snapshot::sslErrors(QNetworkReply *reply, const QList<QSslError> &errors)
{
    reply->ignoreSslErrors();
}
于 2012-05-03T06:01:18.157 に答える