Получение нескольких сигналов loadFinished для запрошенной веб-страницы

Я получаю несколько loadFinished сигналы, когда я пытаюсь загрузить QWebPage и я не уверен, что является причиной проблемы. Было несколько других вопросов, которые, казалось, имели в виду ту же проблему, но решения не помогли мне:

В первом вопросе ответ состоял в том, чтобы подключить сигналы к слотам только один раз, но я уже это делаю. Ответ на второй вопрос предполагает, что я должен подключиться к кадру. loadFinished сигнал, но я просто не получаю необходимые данные, когда это будет сделано.

Я пытаюсь загрузить несколько страниц:

int main(int argc, char *argv[])
{
QApplication app(argc, argv);

QList<QUrl> urls;
urls.append(QUrl("http://www.useragentstring.com/pages/Chrome/"));
urls.append(QUrl("http://www.useragentstring.com/pages/Firefox/"));
urls.append(QUrl("http://www.useragentstring.com/pages/Opera/"));
urls.append(QUrl("http://www.useragentstring.com/pages/Internet Explorer/"));
urls.append(QUrl("http://www.useragentstring.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();
}

Класс, который обрабатывает сигналы, выглядит следующим образом:

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<QWebPage *>(sender());
if(ok && page)
{
qDebug() << _numPageLoadSignals << " loads "<< page->mainFrame()->documentElement().findAll("div#liste ul li a").count()
<< " elements found on: " << page->mainFrame()->requestedUrl().toString();
}
}

void frameLoadFinished(bool ok)
{
_numFrameLoadSignals++;
QWebFrame * frame = qobject_cast<QWebFrame *>(sender());
if(ok && frame)
{
qDebug() << _numFrameLoadSignals << " loads "<<  frame->documentElement().findAll("div#liste ul li a").count()
<< " elements found on: " << frame->requestedUrl().toString();
}
}
};

Вот результат подключения только к кадру loadFinished сигнал:

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

Вот результаты, когда я подключаюсь к странице loadFinished сигнал:

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

Я не понимаю поведение, почему иногда я получаю релевантный контент, а иногда нет. Если я подключусь к странице loadFinished сигнал, тогда я в конечном итоге получу контент, но я не знаю, когда это действительно произойдет. Как я узнаю, когда моя страница действительно закончила загрузку?

Обновить

Я предполагаю, что большая часть моего контента будет доставлена ​​менее чем за 3 секунды, поэтому я нашел обходной путь: я установил событие таймера, чтобы сигнализировать UA::loadFinished 3 секунды после первого loadFinished сигнал получен от QWebPage, Это не очень красиво и не эффективно, но работает в этой ситуации.

3

Решение

Цитирование документации QWebPage:

Наконец, сигнал loadFinished () испускается, когда содержимое страницы загружается полностью, независимо от выполнения скрипта или рендеринга страницы.

Подвох это последняя фраза. Так что некоторые люди в следующей теме указывают на проблему, которой я верю.

Почему QWebView.loadFinished вызывается несколько раз на некоторых сайтах, например YouTube?

Я изо всех сил пытался кодировать сканер, который включает в себя страницы, которые загружают контент, используя JavaScript за кулисами. Несколько loadFinished является проблемой (я хотел бы, чтобы он срабатывал после того, как все улажено.), Но я заметил, что существенная проблема заключается в том, что содержимое веб-страницы все еще не может быть отображено / подготовлено, даже после того, как последний loadFinished активирует слот.

Поэтому я поэкспериментировал со многими сигналами класса QWebPage, чтобы увидеть, последовательно ли срабатывает какой-либо из них после сигнала loadFinished.

Найден один: repaintRequested (QRect)

Я не знаю, работает ли это все время. Но если какой-либо контент влияет на внешний вид веб-страницы, я считаю, что этот сигнал должен быть вызван, чтобы страница считалась завершенной. Я не отображаю страницы и не использую виджет, но сигнал постоянно срабатывает. Единственная проблема в том, что это вызвано много раз (Гораздо чаще, чем loadFinished), поэтому вам нужно проверить, совпадает ли mainFrame-> requiredUrl () с mainFrame-> url () И какое ключевое слово интересующего вас контента существует. (Особенно, если вы повторно используете webPage, как и я. Последующий запрос изменяет запрашиваемый URL, в то время как содержимое mainFrame из предыдущей загрузки все еще там. Некоторое сохранение там)

Хитрость для сокращения количества проверяемых сигналов может заключаться в том, чтобы подключить repaintRequested только после получения сигнала loadFinished от QWebPage (и, возможно, проверки дополнительных условий).

Это может не относиться к бесконечным вложенным нагрузкам, поскольку никто не знает, является ли какой-либо сигнал последним, но если вы ищете контент, то сигнал должен сработать после загрузки этого конкретного контента (я имею в виду интеграцию в DOM 🙂

1

Другие решения

Я решил эту проблему, указав емкость кеша памяти для мертвых объектов, другими словами, я просто отключил кеш памяти QtWebKit, используя:

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

Чтобы узнать больше, здесь ссылка

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

0

По вопросам рекламы [email protected]