gpt4 book ai didi

c++ - 为请求的网页接收多个 loadFinished 信号

转载 作者:太空狗 更新时间:2023-10-29 23:06:44 25 4
gpt4 key购买 nike

当我尝试加载 QWebPage 时,我收到了多个 loadFinished 信号,但我不确定是什么导致了这个问题。还有几个其他问题似乎暗示了同一个问题,但解决方案对我不起作用:

在第一个问题中,答案是只将信号连接到插槽一次,”但我已经这样做了。第二个问题的答案表明我应该连接到框架的 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从 QWebPage 接收到第一个 loadFinished 信号后的秒数。这不是很漂亮,也不是很有效,但它适用于这种情况。

最佳答案

引用QWebPage文档:

Finally, the loadFinished() signal is emitted when the page contents are loaded completely, independent of script execution or page rendering.

关键是最后一句话。因此,以下线程中的一些人指出了我认为的问题。

Why is QWebView.loadFinished called several times on some sites e.g. youtube?

我一直在努力编写一个爬虫程序,该爬虫程序涉及在后台使用 javascript 加载内容的页面。多次 loadFinished 是个问题(我希望它在一切都安定下来之后触发。),但我注意到本质问题是即使在最后一次 loadFinished 激活一个插槽后,网页内容可能仍然没有呈现/准备。

所以我对 QWebPage 类的许多信号进行了试验,以查看是否有任何信号在 loadFinished 信号后始终被触发。

找到一个:repaintRequested(QRect)

我不知道这是否一直有效。但是如果任何内容影响网页的外观,我相信必须调用此信号才能假定页面已完成。我既不显示页面,也不使用 View 小部件,但信号始终被触发。唯一的问题是它被触发了很多次。 (比 loadFinished 更频繁),因此您需要检查 mainFrame->requestedUrl() 是否与 mainFrame->url() 相同,并且是否存在您感兴趣的内容的关键字。 (特别是如果您像我一样重用网页。后续请求会更改 requestedUrl,而先前加载的 mainFrame 内容仍然存在。那里有一些持久性)

减少要检查的信号数量的技巧可能是仅在从 QWebPage 接收到 loadFinished 信号后才连接 repaintRequested(并可能检查额外条件)。

这可能无法解决无限嵌套加载问题,因为人们不知道是否有任何信号是最后一个,但如果您正在搜索内容,那么在加载该特定内容后必然会触发一个信号(我的意思是集成进入 DOM :)

关于c++ - 为请求的网页接收多个 loadFinished 信号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14780261/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com