为啥在某些网站上多次调用 QWebView.loadFinished,例如YouTube?
Posted
技术标签:
【中文标题】为啥在某些网站上多次调用 QWebView.loadFinished,例如YouTube?【英文标题】:Why is QWebView.loadFinished called several times on some sites e.g. youtube?为什么在某些网站上多次调用 QWebView.loadFinished,例如YouTube? 【发布时间】:2012-01-08 03:25:51 【问题描述】:根据文档,只有在所有页面元素完成加载后才应发出 loadFinished。这应该意味着它只会被调用一次,但是我注意到在 youtube.com 等一些网站上,它会被调用两次?有没有其他方法可以绕过这个bug 或者检测 page.load 事件的最可靠方法是什么?
这是测试代码:
import sys
from PyQt4 import QtCore, QtGui, QtWebKit
from PyQt4.QtCore import QUrl
from PyQt4.QtGui import QApplication
def onDone(val):
print "Done ...",val
def onStart():
print "Started..."
app = QApplication(sys.argv)
ui = QtWebKit.QWebView()
ui.loadStarted.connect(onStart)
ui.loadFinished.connect(onDone)
ui.load(QUrl("http://www.youtube.com"))
ui.showMaximized()
sys.exit(app.exec_())
输出:
Started...
Done ... True
Started...
Done ... True
编辑: 有一个几乎相同的question,但它已经超过 2 年了,仍然没有得到答复。
【问题讨论】:
我很确定当你修改 DOM 时会发生这种情况,就像它是一个字符串一样。 我已经发布了代码。 DOM 是如何被修改的?它的简单 url 加载,不是吗?? 我确信 QWebKit 运行的是 JS 代码,所以它可以在 onDone() 之后修改 DOM。这是评论而不是答案。 同意。你说的是真的。当我禁用 javascript 时,它运行良好。所以我应该只处理第一次调用并忽略后续调用 - 这是处理的正确方法还是有更好的选择? 【参考方案1】:每加载一帧,load*
信号就会触发一次。
要仅捕获第一组信号,请连接到主机的相应信号:
ui.page().mainFrame().loadStarted.connect(onStart)
ui.page().mainFrame().loadFinished.connect(onDone)
您可以通过连接到frameCreated
信号来验证是否正在加载其他帧,该信号将为在主帧加载后创建的每个后续帧触发一次:
def onFrame(val):
print 'Frame Created:', val.frameName()
ui.page().frameCreated.connect(onFrame)
【讨论】:
感谢您的回答。但是有一个疑问(不在系统中,所以无法检查自己) - QWebFrame 是否会持续超过渲染页面的生命周期?我的印象是为站点的每个框架创建一个框架,并且一旦加载下一页就应该将其销毁。请原谅我缺乏洞察力,但我对 qt 很陌生。 @Codefreak。如果您在加载新页面之前询问是否需要断开并重新连接信号,答案是:不需要。还要注意,无论网页是否有任何<frame>
或<iframe>
标签,总是有一个mainFrame
对象。
是的,这正是我想知道的。感谢您的信息。
@ekhumoro 我还是不明白,如何检测所有帧都已加载,然后我才会截图?
@holms。我不会说没有机会。我的直觉是解决 general 的情况会非常困难,但如果您愿意施加限制(例如递归深度),那么实际的解决方法应该是可能的。在我的脑海中,我不知道该怎么做,但肯定有其他人以前看过这个问题。这就是为什么我最初建议您应该提出一个新问题 - 以这种方式获得答案的机会要大得多(即更多人会关注它)。【参考方案2】:
我很确定当你修改 DOM 时会发生这种情况,就像它是一个字符串一样。我确信 QWebKit 运行的是 JS 代码,所以它可以在 onDone() 之后修改 DOM。
您可能应该创建一个只触发一次的 onDoneFirst 方法。
【讨论】:
我会等待 24 小时以获得更好的答案。如果我没有得到任何答案,我会接受你的答案。 如果稍后发布更好的答案,您可以更改已接受的答案。如果答案有帮助,我们鼓励您投票。请参考***.com/privileges/vote-up和***.com/privileges/create-posts以上是关于为啥在某些网站上多次调用 QWebView.loadFinished,例如YouTube?的主要内容,如果未能解决你的问题,请参考以下文章
为啥在循环内调用 publishProgress 并多次调用(没有循环)会显示不同的行为?
为啥 componentDidMount 在 react.js 和 redux 中被多次调用?
android - 为啥在 HorizontalPager.OnScrollListener() 接口中多次调用 onViewScrollFinished