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

Согласно документации, loadFinished должно генерироваться только после завершения загрузки всех элементов страницы. Это должно означать, что он будет вызываться только один раз, однако я заметил, что на некоторых сайтах, таких как youtube.com, он вызывается дважды? Есть ли другой способ обойти эту ошибку или какой самый надежный способ обнаружить событие 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

Изменить: Существует почти тот же вопрос, но его> 2 года и до сих пор без ответа.

2 ответа

Решение

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)

Я совершенно уверен, что это происходит, когда вы изменяете DOM, как если бы это была строка. Я уверен, что QWebKit запускает код JS, поэтому он может изменить DOM после того, как он был включен в onDone().

Вероятно, вам следует создать метод onDoneFirst, который запускается только один раз.

Другие вопросы по тегам