Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Pobieranie strony WWW/HTML z sieci za pomocą Qt

    Polish
    www html strona internet internet socket parsowanie parsowanie stro
    3
    9
    3388
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • H
      Huragan last edited by Huragan

      Pewnie wielu z Was zastanawiało się jak w prosty sposób można pobrać zawartość sieci, konkretnie stronę web za pomocą Qt i wykorzystać ją do własnych celów. Właśnie sam się nad tym zastanawiam.
      Podobno można wykorzystać klasę QNetworkAccessManager.
      Jeśli uda mi się coś napisać to na pewno zamieszczę tu rozwiązanie. Jeśli zaś Wy już macie swoje rozwiązania na ten problem zapraszam do dyskusji. ;)

      Śmieje się, bo życie jest śmiechu warte. - Petroniusz "Quo Vadis"

      1 Reply Last reply Reply Quote 0
      • T
        turaz last edited by turaz

        Cześć tutaj na forum masz opisane w jaki sposób powinno być to wykonane: https://forum.qt.io/topic/3352/qnetworkaccessmanager-doesn-t-download-whole-web-page
        W skrócie dość prosto korzystasz z metody QNetworkAccesManager::get() i swoim slotem podpinasz się pod sygnał: QNetworkAccesManager::finished() następnie odczytujesz dane poprzez readAll()

        1 Reply Last reply Reply Quote 0
        • H
          Huragan last edited by Huragan

          Niestety mnie się nie udaje za pomocą sygnałów, QNetworkAccesManager, QNetworkReply i QNetworkRequest. Mój kod wygląda tak... ale nie ma żadnej reakcji.

          qDebug() << "Pobieranie strony WWW";
          QNetworkAccessManager manager;
          QNetworkReply *odpowiedz = NULL;
          QNetworkRequest request;
          //request.setRawHeader("User-Agent", "MyOwnBrowser 1.0");
          request.setHeader(QNetworkRequest::UserAgentHeader, "Cos 1.1");
          request.setPriority( QNetworkRequest::HighPriority );
          
          request.setUrl( QUrl( "http://www.theravenlords.za.pl" )); 
                  //"http://old.radiopolska.pl/wykaz/galeria.php?l=A#0") );
          odpowiedz = manager.get( request );
          
          connect( odpowiedz, SIGNAL(finished()), this, SLOT( slot_ReplyFinished() ));
          connect( odpowiedz, SIGNAL(readyRead()), this, SLOT(slot_ReadyRead()));
          
          connect( odpowiedz, SIGNAL( error(QNetworkReply::NetworkError) ), this, SLOT( slot_blad() ));
          connect( odpowiedz, SIGNAL( sslErrors(QList<QSslError>)), this, SLOT( slot_SslBlad() ));
          

          Oczywiście slot_ReplyFinished() , slot_ReadyRead(), slot_blad(), slot_SslBlad() są moimi, przeze mnie zaprogramowanymi slotami. Wyglądało by na to, że sygnał finished() emitowany przez QNetworkReply nigdy nie jest emitowany.

          Co Wy na to ? :)

          Śmieje się, bo życie jest śmiechu warte. - Petroniusz "Quo Vadis"

          1 Reply Last reply Reply Quote 0
          • T
            turaz last edited by

            Problemem jest czas życia obiektu manager
            Zamień to:
            QNetworkAccessManager manager;
            na:
            QNetworkAccessManager *manager = new QNetworkAccessManager(this);
            Powinno pomóc :)

            1 Reply Last reply Reply Quote 0
            • H
              Huragan last edited by Huragan

              O właśnie, wielgaśne dzięki. :)
              Dziś w dzień jak siedziałem nad tym zagadnieniem na korytarzu mojej uczelni doszedłem do tego rozwiązania, tylko tyle, że nie wiedziałem, że się to nazywa "czasem życia obiektu".
              Możesz mi wytłumaczyć dla czego ma to wpływ?
              Bo ja zrozumiałem, że jakoś, z tego powodu nie jest wywoływany sygnał finished() przez QNetworkAccessManager.

              W przypadku kiedy pisałem:

                QNetworkAccessManager manager;
                connect(&manager, SIGNAL( finished() ), this, SLOT( slot_zakonczony() ) );
              

              kod zdawał się nie działać, zawartość strony nie była pobierana...
              a w przypadku, kiedy robiłem tak jak zapisałeś poprzez wskaźnik i new kod działał.

              Śmieje się, bo życie jest śmiechu warte. - Petroniusz "Quo Vadis"

              1 Reply Last reply Reply Quote 0
              • T
                turaz last edited by

                W telegraficznym skrócie i maksymalnej prostocie to tworząc obiekt w jakiejś metodzie w taki sposób:
                QNetworkAccessManager manager;
                zostaje on niszczony po zakończeniu działania metody w której został stworzony. W związku z tym, że QNetworkAccessManager działa asynchronicznie i jego obiekt zostanie zniszczony przed zakończeniem requesta to sygnał nie zostanie wyemitowany.

                Tworząc obiekt przez operator 'new' nie zostanie on zniszczony po wyjściu z metody, lecz musisz pamiętać by samemu usunąć go w momencie gdy nie będzie Ci już potrzebny używając delete lub (zalecany dla QObjectów) deleteLater().
                Jeżeli tworząc obiekt przez operator new podasz mu w konstruktorze parenta to zostanie on zniszczony wraz z swoim rodzicem (gdybyś go sam nie usunął). Jeżeli nie usuniesz obiektu będziesz miał doczynienia z wyciekiem pamięci.
                W ramach nauki możesz stworzyć sobie dowolny QObject i podpiąć się slotem pod sygnał destroyed() wtedy zobaczysz kiedy jest on niszczony. :)
                Pozdrawiam.

                H 1 Reply Last reply Reply Quote 1
                • cybercatalyst
                  cybercatalyst last edited by

                  Ja nie mowie za bardzo po polsku, jestem z niemec. Ale moze zrozumiece co pisze :) Use QEventLoop:

                  QNetworkAccessManager nam;
                  
                  // Request
                  QNetworkRequest request;
                  request.setUrl(QUrl("http://www.google.de"));
                  QNetworkReply *reply = nam.get(request);
                  
                  // Wait for server answer
                  QEventLoop loop;
                  connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
                  loop.exec();
                  
                  // Read resoinse
                  QByteArray response = reply->readAll(); // response == website data
                  
                  H 1 Reply Last reply Reply Quote 1
                  • H
                    Huragan @turaz last edited by Huragan

                    @turaz
                    Dzięki wielkie Turaz, rozjaśniłeś mi sprawę. :) W sumie masz rację, wcześniej nie dostrzegałem problemu długości życia zmiennych i wysyłanych przez nie sygnałów, teraz to widzę. :)
                    Żeby connect() zadziałał utworzony prze zemnie obiekt musi istnieć po zakończeniu funkcji, a jak deklaruje go zwyczajnie/niedynamicznie to obiekt przestaje istnieć po zakończeniu funkcji w której jest tworzony. W sumie nawet zmienna - wskaźnik do utworzonego obiektu za pomocą operatora new też przestaje istnieć, więc pewnie wewnątrz funckji connect() robiona jest kopia wskaźnika... hmm... w sumie zawsze to tak działało. :)
                    Dzięki wielkie za pomoc, zrobiłem sobie przy okazji praktyczne powtórzenie materiału. :)

                    Śmieje się, bo życie jest śmiechu warte. - Petroniusz "Quo Vadis"

                    1 Reply Last reply Reply Quote 0
                    • H
                      Huragan @cybercatalyst last edited by

                      @cybercatalyst
                      Rozumiemy, nie martw się. :)
                      Nigdy, jak dotąd nie korzystałem z klasy QEventLoop. Dzięki za podsunięcie pomysłu, kolejnego sposobu na rozwiązanie tego problemu. :)

                      [ENG] If you don't understand what I wrote, I can rewrite this at english. :) I suppose you speak english. :)

                      Śmieje się, bo życie jest śmiechu warte. - Petroniusz "Quo Vadis"

                      1 Reply Last reply Reply Quote 0
                      • First post
                        Last post