当我尝试加载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
收到1}}信号。这不是很漂亮,也不是很有效,但它适用于这种情况。
答案 0 :(得分:1)
引用QWebPage文档:
最后,在完全加载页面内容时发出loadFinished()信号,与脚本执行或页面呈现无关。
抓住的是最后一句话。因此,以下主题中的某些人指出了我认为的问题。
Why is QWebView.loadFinished called several times on some sites e.g. youtube?
我一直在努力编写一个爬虫程序,它涉及在幕后使用javascript加载内容的页面。多个loadFinished是一个问题(我希望它能在一切安定下来之后触发。)但是我注意到,基本的问题是,即使在最后一个loadFinished激活一个插槽后,网页内容仍然无法呈现/准备。
所以我尝试了很多QWebPage类的信号,看看在loadFinished信号之后是否一直触发它们。
找到一个:repaintRequested(QRect)
我不知道这是否一直有效。但是,如果任何内容影响网页的外观,我相信必须调用此信号才能使页面完整。我既不显示页面,也不使用视图小部件,但信号始终被触发。唯一的问题是它被多次触发。 (比loadFinished更常见),因此您需要检查mainFrame-&gt; requestedUrl()是否与mainFrame-&gt; url()相同,并且您感兴趣的内容的关键字是否存在。 (特别是如果你像我一样重复使用webPage。后续请求会更改requestedUrl,而之前加载的mainFrame内容仍然存在。那里有一些持久性)
减少要检查的信号数量的技巧可能是仅在从QWebPage接收到loadFinished信号后才连接repaintRequested(并且可能检查额外的条件)。
这可能无法解决无限的嵌套加载,因为人们不知道是否有任何信号是最后一个,但如果您正在搜索内容,那么在加载特定内容后必然会触发信号(我的意思是集成)进入DOM:)
答案 1 :(得分:0)
我解决了这个问题,指明死对象的内存缓存容量,换句话说,我只是使用以下命令禁用QtWebKit内存缓存:
QWebSettings::setObjectCacheCapacities(0, 0, 0);
要了解更多信息,请点击链接
http://qt-project.org/doc/qt-4.8/qwebsettings.html#setObjectCacheCapacities