Verständnissfrage zu QNetworkAccessManager


  • Mod

    Ist ja gerade sinn der Sache, das das Programm nicht blockiert.
    Frage mich allerdings ob QNetworkAccessManager das richtige für dich ist, du bekommst hier mehr oder weniger nur das rohe HTML geliefert, oder auch alles andere was dir der Webserver zurück sendet.

    Evtl. ist QWebKit hier der bessere Ansatz, damit kannst du auch das HTML durchsuchen etc.
    Das ist gerade dann praktisch, wenn eine Seite erst effektiv durch JS benutzbar wird.



  • Das ist natürlich eine gute Fragestellung. QWebKit scheint an sich eine ganz gute Lösung zu sein. Besonders gefällt mir der Umstand, dass ich per DOM auf die Elemente zugreifen kann, was mir ein Gemetzel mit RegEx erspart. Allerdings ist mir noch nicht ganz klar, ob ich mit den QWebKit-Klassen einen Browser simulieren kann. Beim Login müsste ich logischerweise erst die Login-Daten eingeben und danach die Form bestätigen. Leider habe ich dazu bis jetzt noch nichts Brauchbares gefunden.

    Zudem weiss ich auch nicht, ob dieses Vorgehen möglicherweise unnötig Ressourcen verbraucht. Schliesslich muss mein Programmen nichts anzeigen, es muss nur automatisiert Daten auslesen, verarbeiten und eingeben.

    Danke schonmal für die vielen schnellen und konstruktiven Beiträge.



  • Sorry für den Doppelpost. Ich habe vergessen etwas wichtiges zu erwähnen.

    Ist ja gerade sinn der Sache, das das Programm nicht blockiert.

    Das Blockieren wäre an sich kein Problem, da ich das Programm in einen Worker-Thread auslagern wollte, welcher per Signals Daten an den Main-Thread sendet. Wenn jemand eine bessere Lösung hat, kann er die natürlich gerne posten.



  • Qute schrieb:

    Allerdings ist mir noch nicht ganz klar, ob ich mit den QWebKit-Klassen einen Browser simulieren kann.

    Es IST ein Browser. Allerdings ist so eine Lösung alles andere als schön. Genauso wie Regex, vergiss es gleich wieder. Es gibt genug Html Parser Bibliotheken für alle Sprachen im Internet, wo du auch einen DOM bekommst.



  • Hallo, ich habe in der Dokumentation dieses Beispiel gefunden:
    http://doc.qt.digia.com/4.6/network-blockingfortuneclient.html

    Bis jetzt funktioniert das Multi-Threading ausreichend gut(ich kenne aber schon die Lösungen für diese Probleme), doch ich habe blöderweise ein Problem ein QByteArray in einen QString zu konvertieren:

    ...
    qDebug() << "begin request";
    reply = manager.get(QNetworkRequest(QUrl("http://www.google.de/")));
    connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
    loop.exec();
    qDebug() << "finished request";
    mutex.lock();
    a = reply->readAll();
    QString answer(a);
    answer.remove("\0");
    qDebug() << answer;
    mutex.unlock();
    reply->deleteLater();
    ...
    

    Leider wird das QByteArray 'a' nicht in den QString 'answer' konvertiert. Praktisch gesehen, passiert einfach nichts;es steht nichts in der der Debug-Konsole. Auch Methoden wie fromAscii(a, a.count()-1) helfen nicht. Allerdings stehen die richtigen Werte im QByteArray. Die Null-Bytes bereinige ich auch schon ===> ich habe ehrlich gesagt keine Ahnung mehr was ich falsch mache.



  • Schaut irgendwie komisch aus. answer.remove("\0"); brauchst du sicher nicht. Warum deleteLater und nicht gleich? Ich würds mal mit UTF8 und nicht ascii probieren, bzw. gleich das richtige Encoding auslesen.
    So auf den ersten Blick seh ich keinen Fehler. Lass die Debug Ausgaben doch weg und debugs einfach durch, dann siehst du sofort, was in den Variablen steht und wo was schiefgeht.



  • Schaut irgendwie komisch aus. answer.remove("\0"); brauchst du sicher nicht.

    Das Entfernen änder nichts.

    Ich würds mal mit UTF8 und nicht ascii probieren

    UTF8 funktioniert auch nicht.

    Warum deleteLater und nicht gleich?

    Da war ich mir nicht ganz sicher. Wenn man QNetworkReply als Argument im Slot übergeben kriegt, muss man es mit deleteLater() löschen. Da ich QNetworkReply aber als Rückgabewert speichere, wusste ich nicht genau, was ich damit machen soll. deleteLater() hat sich erstmal am sichersten angehört.

    Lass die Debug Ausgaben doch weg und debugs einfach durch, dann siehst du sofort, was in den Variablen steht und wo was schiefgeht.

    Mein Debugger funktionierte nicht richtig. Ich habe ihn jetzt anhand von Google (hoffentlich langfrisitg) richtig eingerichtet. Beim debuggen wird der richtige Inhalt angezeigt. Warum qDebug den String nicht ausgeben will, weiss ich allerdings nicht.
    Danke nochmal für eure Antworten!



  • Ich hatte auch irgendwann mal das Problem, dass qDebug nicht funktioniert hat. Konnte das damals auch nicht nachvollziehen, war mir auch nicht wichtig.
    Aber dass dein Debugger nicht richtig funktioniert hat, find ich schon viel kritischer 😉 Ohne Debugger kann man überhaupt nicht sinnvoll arbeiten.


  • Mod

    Lass dir mal mit qDebug die Größe des Strings anzeigen, oder die ersten n Zeichen.
    Wenn du im Debugger siehst, das es da ist, kannst du ja schon mal den nächsten Schritt versuchen.

    Und mal so neben bei gefragt, wieso verbindest du finished() mit quit()?
    Dir ist schon klar, das dies eine Asynchrone API ist, und dein Code mit mutex in den Handler gehört?
    Hier findest du ein Beispiel für HTTP mit Qt:
    http://www.developer.nokia.com/Community/Wiki/Creating_an_HTTP_network_request_in_Qt



  • Ich habe mich nochmal eingelesen und einen erneuten [bis jetzt erfolgreichen Versuch] gestartet. Das Problem war wahrscheinlich, dass Google mich redirected hat. Deswegen hatte das Paket auch keinen Inhalt.
    Die redirection-Url kann man über

    if (!(sRedirection = _reply->attribute(QNetworkRequest::RedirectionTargetAttribute)).isNull()) 
        qDebug() << sRedirection.toString();
    

    abfragen.

    Und mal so neben bei gefragt, wieso verbindest du finished() mit quit()?
    Dir ist schon klar, das dies eine Asynchrone API ist

    Ja, und genau deswegen benutze ich eine EventLoop. Ich möchte einen synchronen Wrapper erstellen.


Anmelden zum Antworten