Réception de plusieurs signaux loadFinished pour une page Web demandée

Je reçois plusieurs signaux loadFinished lorsque loadFinished de charger une QWebPage et je ne suis pas sûr de la cause du problème. Il y avait quelques autres questions qui semblaient faire allusion au même problème, mais les solutions ne m’ont pas fonctionné:

  • QtWebPage – loadFinished () appelé plusieurs fois
  • Signal QWebPage :: loadFinished (bool) renvoie deux fois?

Dans la première question, la réponse consistait à ne connecter les signaux aux slots qu’une seule fois “, mais je le fais déjà. La réponse à la deuxième question suggère que je devrais me connecter au signal loadFinished la trame, mais je ne reçois tout simplement pas les données nécessaires. quand cela est fait.

Je tente de charger plusieurs pages:

 int main(int argc, char *argv[]) { QApplication app(argc, argv); QList urls; urls.append(QUrl("http://www.useragentssortingng.com/pages/Chrome/")); urls.append(QUrl("http://www.useragentssortingng.com/pages/Firefox/")); urls.append(QUrl("http://www.useragentssortingng.com/pages/Opera/")); urls.append(QUrl("http://www.useragentssortingng.com/pages/Internet Explorer/")); urls.append(QUrl("http://www.useragentssortingng.com/pages/Safari/")); foreach(QUrl url, urls) { UA* ua = new UA(); QWebPage* page = new QWebPage(); //QObject::connect(page, SIGNAL(loadFinished(bool)), ua, SLOT(pageLoadFinished(bool))); QObject::connect(page->mainFrame(), SIGNAL(loadFinished(bool)), ua, SLOT(frameLoadFinished(bool))); // Load the page page->mainFrame()->load(url); } return app.exec(); } 

La classe qui traite les signaux ressemble à ceci:

 class UA:public QObject { Q_OBJECT private: int _numPageLoadSignals; int _numFrameLoadSignals public: UA() { _numPageLoadSignals = 0; _numFrameLoadSignals = 0; } ~UA(){} public slots: void pageLoadFinished(bool ok) { _numPageLoadSignals++; QWebPage * page = qobject_cast(sender()); if(ok && page) { qDebug() << _numPageLoadSignals << " loads " <mainFrame()->documentElement().findAll("div#liste ul li a").count() << " elements found on: " <mainFrame()->requestedUrl().toSsortingng(); } } void frameLoadFinished(bool ok) { _numFrameLoadSignals++; QWebFrame * frame = qobject_cast(sender()); if(ok && frame) { qDebug() << _numFrameLoadSignals << " loads " <documentElement().findAll("div#liste ul li a").count() << " elements found on: " <requestedUrl().toSsortingng(); } } }; 

Voici le résultat de la connexion au signal loadFinished du cadre:

 1 loads 0 elements found on: "http://www.useragentssortingng.com/pages/Safari/" 1 loads 0 elements found on: "http://www.useragentssortingng.com/pages/Chrome/" 1 loads 0 elements found on: "http://www.useragentssortingng.com/pages/Opera/" 1 loads 0 elements found on: "http://www.useragentssortingng.com/pages/Firefox/" 1 loads 241 elements found on: "http://www.useragentssortingng.com/pages/Internet Explorer/" 

Voici les résultats lorsque je me connecte au signal loadFinished la page:

 1 loads 0 elements found on: "http://www.useragentssortingng.com/pages/Safari/" 1 loads 0 elements found on: "http://www.useragentssortingng.com/pages/Chrome/" 1 loads 0 elements found on: "http://www.useragentssortingng.com/pages/Firefox/" 1 loads 0 elements found on: "http://www.useragentssortingng.com/pages/Internet Explorer/" 2 loads 576 elements found on: "http://www.useragentssortingng.com/pages/Safari/" 2 loads 782 elements found on: "http://www.useragentssortingng.com/pages/Chrome/" 2 loads 241 elements found on: "http://www.useragentssortingng.com/pages/Internet Explorer/" 2 loads 1946 elements found on: "http://www.useragentssortingng.com/pages/Firefox/" 3 loads 241 elements found on: "http://www.useragentssortingng.com/pages/Internet Explorer/" 3 loads 1946 elements found on: "http://www.useragentssortingng.com/pages/Firefox/" 3 loads 782 elements found on: "http://www.useragentssortingng.com/pages/Chrome/" 1 loads 964 elements found on: "http://www.useragentssortingng.com/pages/Opera/" 3 loads 576 elements found on: "http://www.useragentssortingng.com/pages/Safari/" 

Je ne comprends pas le comportement, pourquoi parfois je reçois un contenu pertinent et d’autres fois non. Si je me connecte au signal loadFinished la page, loadFinished éventuellement le contenu, mais je ne sais pas quand cela se produira réellement. Comment savoir quand le chargement de ma page est terminé?

Mettre à jour

Je suppose que la plus grande partie de mon contenu arrivera dans moins de 3 secondes. J’ai donc proposé une solution de contournement: je règle un événement timer pour signaler à l’ UA::loadFinished 3 secondes après le premier signal loadFinished QWebPage . Ce n’est pas très joli, ni efficace, mais cela fonctionne dans cette situation.

Citant la documentation QWebPage:

Enfin, le signal loadFinished () est émis lorsque le contenu de la page est chargé complètement, indépendamment de l’exécution du script ou du rendu de la page.

La prise est cette dernière phrase. Donc, certaines personnes dans le fil suivant pointent vers le problème, je crois.

Pourquoi QWebView.loadFinished est-il appelé plusieurs fois sur certains sites, par exemple YouTube?

J’ai eu du mal à coder un robot qui implique des pages qui chargent du contenu à l’aide de javascript en arrière-plan. Le chargement multiple est un problème (je souhaite qu’il soit déclenché une fois que tout est réglé.), Mais j’ai remarqué que le problème essentiel est que le contenu de la page Web peut toujours ne pas être restitué / préparé même après que le dernier chargement a activé un emplacement.

J’ai donc expérimenté de nombreux signaux de la classe QWebPage pour voir si l’un d’entre eux est systématiquement déclenché après le signal loadFinished.

Trouvé un: repaintRequested (QRect)

Je ne sais pas si cela fonctionne tout le temps. Mais si un contenu quelconque affecte l’apparence d’une page Web, je pense que ce signal doit être appelé pour que la page soit considérée comme complète. Je n’affiche ni les pages, ni l’utilisation d’un widget de vue, mais le signal est toujours déclenché. Le seul problème est qu’il est déclenché plusieurs fois. (Beaucoup plus souvent que loadFinished), vous devez donc vérifier si le paramètre mainFrame-> wantedUrl () est identique à mainFrame-> url () ET un mot-clé du contenu qui vous intéresse existe. (Surtout si vous réutilisez la page Web comme moi. Une requête ultérieure modifie le requestUrl, tandis que le contenu mainFrame d’un chargement précédent est toujours présent. Un peu de persistance là-bas)

Une astuce pour réduire le nombre de signaux à vérifier pourrait être de se connecter repaintRequested uniquement après avoir reçu un signal loadFinished de QWebPage (et éventuellement en vérifiant des conditions supplémentaires).

Cela peut ne pas adresser les charges nestedes infinies, car on ne sait pas si un signal est le dernier, mais si vous recherchez un contenu, un signal doit obligatoirement être déclenché après le chargement de ce contenu spécifique (je veux dire intégré au DOM 🙂

J’ai résolu ce problème en spécifiant les capacités de cache mémoire pour les objects morts. En d’autres termes, je désactive simplement le cache mémoire QtWebKit en utilisant:

 QWebSettings::setObjectCacheCapacities(0, 0, 0); 

Pour en savoir plus, voici le lien

http://qt-project.org/doc/qt-4.8/qwebsettings.html#setObjectCacheCapacities