Search code examples
pythonqtwebkitpysideqtwebkit

QWebPage - Getting a list of resources / Verifying page loaded with no errors


I am loading a webpage in PySide. I want to be able to see if it has loaded successfully without errors. If I get an error, then I want to know about it. I can not simply use the "success" parameter to the load finished signal, as it seems to always indicate success. The only way I know how to do it, is to do something like this:

class WebPageResourceTracker(
    PySide.QtCore.QObject
):
    def __init__(self, url):
        PySide.QtCore.QObject.__init__(self)
        self.page = PySide.QtWebKit.QWebPage()
        self.frame = self.page.currentFrame()

        # The reason for the lambda is that otherwise I get this:
        #ASSERT: "self" in file /var/tmp/portage/dev-python/pyside-1.1.0/work/pyside-qt4.7+1.1.0/libpyside/signalmanager.cpp, line 534
        self.frame.loadFinished.connect(lambda ok: self.onLoadFinished(ok))
        self.page.networkAccessManager().finished.connect(lambda reply: self.onResourceFinished(reply))

        self.frame.setUrl(
            PySide.QtCore.QUrl(
                url,
            )
        )


    def onLoadFinished(self, ok):
        print 'onLoadFinished', ok

    def onResourceFinished(self, reply):
        print 'onResourceFinished', reply.url().toString(), reply.error()



import sys
from PySide import QtGui

app = QtGui.QApplication(sys.argv)
#WebPageResourceTracker("http://google.com")
WebPageResourceTracker(
    "http://migration.tanagerproductions.com/broken.html"
)
sys.exit(app.exec_())

But, I would imagine there would be a way to directly access a list of resources for the page, because the webkit inspector, can list off resources...

Bonus: I would also like to know if there is any JavaScript errors in the page, how would I do this?


Solution

  • One way to do this would be to first create a new class inheriting from QNetworkManager that overrides QNetworkAccessManager::createRequest. In your createRequest function you would first call the base/super class to get the request, then connect to the QNetworkReply::error signal or QNetworkReply::finished and check the QNetworkReply::error function.

    You then set this custom QNetworkAccessManager on the QWebPage with QWebPage::setNetworkAccessManager.

    To intercept JavaScript messages, you create a new class inheriting from QWebPage that overrides QWebPage::javaScriptConsoleMessage. Any errors or calls to console.log will be passed to this function:

    This function is called whenever a JavaScript program tries to print a message to the web browser's console. For example in case of evaluation errors the source URL may be provided in sourceID as well as the lineNumber.

    Note: This answer assumes that PySide provides the full Qt API, I haven't actually checked this is possible in Python, but it's the way I've previously done similar things in C++.