Bestimmten Inhalt aus HTML-Datei (URL) auslesen



  • Guten Tag,

    vorab: ich bin "fortgeschrittener Anfänger", kenne mich also mehr oder weniger nur mit den Grundlagen aus.
    Mit was ich arbeite: Qt Creator, C++.

    Nun möchte ich, bestimmte Inhalte einer HTML-Datei auslesen, wie z.B. die aktuelle Temperatur auf https://www.wetter.com/deutschland/konstanz/DE0005678.html

    Das wäre in der HTML-Datei wohl folgende Zeile
    <div class="text--white beta">26°C</div>

    Das heißt, ich muss irgendwie den Inhalt zwischen
    <div class="text--white beta">
    und </div> auslesen. So hatte ich es jedenfalls damals in VB.NET realisiert.

    Das heißt, ich muss grob in folgenden Schritten vorgehen:

    1. Den kompletten HTML-Inhalt über die URL einlesen,
    2. den Inhalt zwischen <div class="text--white beta"> und </div> auslesen,
    3. den ausgelesenen Inhalt (also die Temperatur) z.B. in ein Label anzeigen lassen.

    Nun weiß ich aber nicht wie ich vorgehen soll. Vielleicht mag mir ja jemand helfen, wie ich nun anfangen kann dies zu realisieren. Vielen Dank



    1. Zum abfragen der Seite oder einer API würde ich libcurl nehmen.
      Das "simple interface" ist einfach zu benutzen.
    2. Dann würde ich erstmal prüfen ob du nicht lieber eine API nutzen willst (ICH EMPFEHLE DAS DRINGEND). Es gibt diverse Anbieter für Wetterdaten, wo man auch kostenlos wetterdaten abfragen kann. Dafür generiert man sich einen Token (Edit: Der anbieter gibt einem die), den man für die Anfragen benutzt. Das limit ist meist ein Zeitlimit. Eine Abfrage pro X sekunden ist erlaubt.
    3. Wenn du dich dagegen entscheidest würde ich nicht die komplette seite parsen, sondern mich mit string suchen durchhangeln bis zur gewünschten Stelle. Der Haken ist, dass alles zerbricht, wenn sich die Webseite ändert, deswegen der Hinweis mit der API.
    4. Die Anzeige im Label bekommst du bestimmt hin ^^


  • Danke für Deine Hilfe. Ich werde es erstmal ohne API probieren, aber danke für den wertvollen Tipp!

    Qt kennt libcurl leider nicht. Ich habe es schon mit
    #include <curl/curl.h>
    versucht, aber der Compiler sagt "'curl/curl.h' file not found'".

    edit:
    Ich konnte es nun mit #include <QUrl> hinzufügen.

    Ich werde es mal weiter versuchen, mal schauen wie weit ich komme...



  • Du verwechselst da etwas: du benötigst die externe Lib curl, nicht die Qt-Klasse QUrl (welche zur Auflösung von URLs existiert).
    Die Curl-Lib mußt du herunterladen und dann zu deinem Projekt hinzufügen (Include- und Linkerpfad, sowie die Lib selbst).

    Alternativ unter Windows kannst du auch URLDownloadToFile benutzen.

    Edit: Unter Qt gibt es dazu die QNetwork...-Klassen, s.a. Daten von URL herunterladen (und QUrl wird nur zur Angabe der URL verwendet, nicht zum eigentlichen herunterladen).



  • Danke für die Korrektur! Da hätte ich ja lange suchen können... Dann lad ich mal die curl-Lib und versuche es mal.



  • Habe gerade noch meinen Beitrag bzgl. Qt editiert (falls du es eh schon verwendest).



  • @Th69 sagte in Bestimmten Inhalt aus HTML-Datei (URL) auslesen:

    QNetwork

    Das heißt, QNetwork würde reichen und ich muss nichts externes runterladen?



  • Ja entschuldigung, ich habe Qt vergessen, dass da ohnehin ne Menge dabei ist.
    Ein einfaches Beispiel hat Th69 ja schon verlinkt.



  • Ja, siehe dir das Beispielprogramm im Link an (kopiere dir einfach die Klasse FileDownloader in eine eigene Datei und dann kannst du sie einfach benutzen).
    In dem von downloadedData() zurückgegebenen QByteArray steht dann der (statische) Inhalt der heruntergeladenen Datei (z.B. HTML).

    PS: Ich hoffe, du kennst dich bei Qt schon mit Signals und Slots aus?



  • Danke, das werde ich machen. Ihr seid echt Klasse. Komme mir vor wie der letzte Depp^^

    Ja, das Signal- und Slot-Konzept sagt mir was. Als ich mit Qt angefangen habe, habe ich die Sachen auch manuell eingerichtet, also z.B. auf Button-Klicks reagieren usw., damit ich das Prinzip verstehe. Ob ich das auch alles tatsächlich verstanden habe, wird sich jetzt zeigen



  • Ich möchte dir nochmal den API weg näher legen:

    Hier kann man wetterdaten abfragen:

    • aufrufen: https://openweathermap.org/api
    • anmelden (gratis, 1 mill abfragen pro monat. )
    • Dann sobald abgeschlossen und angemeldet auf das Profile gehen unter "API keys"
    • Api key generieren.

    Und dann kannst du für das aktuelle Wetter eine der folgenden URLs aufrufen:

    api.openweathermap.org/data/2.5/weather?q={city name}&appid={your api key}
    api.openweathermap.org/data/2.5/weather?q={city name},{state code}&appid={your api key}
    api.openweathermap.org/data/2.5/weather?q={city name},{state code},{country code}&appid={your api key}
    

    Beispiel:

    api.openweathermap.org/data/2.5/weather?q=Hannover,de&appid=IMAGINÄRERHEXCODE
    

    Dabei kommt dann JSON bei raus:
    https://cdn.discordapp.com/attachments/725722101444771911/725722116456054874/unknown.png
    (oder roh)
    https://cdn.discordapp.com/attachments/725722101444771911/725722283687280680/unknown.png

    Das kannst du aufdröseln entweder mit stringsuche, was hier viel einfacher ist als in HTML, oder du nimmst https://github.com/nlohmann/json
    Ist header only, also keine library die gebaut und gelinked werden muss, ein include reicht.

    mit nlohmann json:

    using json = nlohmann::json;
    auto j = json::parse(myApiResponseString);
    auto temp = j["main"]["temp"].get<float>() - 273.15f;
    


  • 5cript, danke für die Demonstration. Das Konzept überzeugt auch und ist durchaus sinnvoller als ohne API, jedoch möchte ich es ohne API versuchen, einfach nur um es zu verstehen und zu können. Ich habe kein ernsthaftes Projekt vor. Das hätte ich vielleicht erwähnen sollen, dann hätte ich Euch etwas Arbeit erspart. Daher möchte ich es erstmal ohne API probieren, und wenn ich tatsächlich mal was ernsthaftes Programmieren will, würde ich es mit API machen.



  • Ich habe mal das Beispielprogramm aus dem Link von Th69 (https://wiki.qt.io/Download_Data_from_URL/de) so ausprobiert wie es da steht, also als Image-Downloader. Das funktioniert aber nur mit HTTP-Verbindungen und nicht mit HTTPS-Verbindungen. Das war mir damals auch schon mal aufgefallen als ich einen kleinen Webbrowser programmierte.

    Was ist das Problem und wie lässt sich es lösen?



  • https://doc.qt.io/qt-5/qnetworkaccessmanager.html#connectToHostEncrypted

    Da es diese Funktion gibt müsste das ganze auch prinzipiell TLS fähig sein.



  • Setze mal setStrictTransportSecurityEnabled(true).

    Aber generell müßte HTTPS auch so funktionieren. Welche Qt-Version nutzt du denn?



  • @Th69, ich habe jetzt folgendes einfach in die MainWindow geschrieben:

    QNetworkAccessManager mgr;
    mgr.setStrictTransportSecurityEnabled(true);

    Ist das so richtig oder muss ich noch was machen? Das Problem besteht immer noch.

    Ich nutze den Qt Creator 4.8.0. (Based on Qt 5.12.0)



  • Wenn, dann auf dem Member FileDownloader::m_WebCtrl anwenden, d.h im Konstruktor (setStrictTransportSecurityEnabled ist ja keine statische Memberfunktion).



  • Hab ich gemacht, leider ohne Erfolg



  • Dann versuche mal request.setSslConfiguration(QSslConfiguration::defaultConfiguration()); (ebenfalls im FileDownloader- Konstruktor), s.a. Example for QNetworkAccessManager with SSL.

    Und schau mal ob die beiden Dateien "libeay32.dll" und "ssleay32.dll" bei Qt schon dabei sind (oder ob du sie noch herunterladen mußt).



  • Funktioniert leider immer noch nicht. Der Konstruktor sieht nun so aus:

    FileDownloader::FileDownloader(QUrl imageUrl, QObject *parent) :
        QObject(parent)
    {
        connect(&m_WebCtrl, SIGNAL (finished(QNetworkReply*)), SLOT (fileDownloaded(QNetworkReply*)));
    
        QNetworkRequest request(imageUrl);
        request.setSslConfiguration(QSslConfiguration::defaultConfiguration());
        m_WebCtrl.get(request);
    }
    

    Es sind 2 libeay32.dll-Dateien und zwei ssleay32.dll-Dateien vorhanden, und zwar :

    Qt\Qt5.12.0\Tools\QtCreator\bin\libeay32.dll
    Qt\Qt5.12.0\Tools\mingw730_64\opt\bin\libeay32.dll

    und

    Qt\Qt5.12.0\Tools\QtCreator\bin\ssleay32.dll
    Qt\Qt5.12.0\Tools\mingw730_64\opt\bin\ssleay32.dll


Anmelden zum Antworten