如何检查javascript是否已完成在pyqt5中的加载?

时间:2019-04-10 20:14:45

标签: javascript python pyqt5

我用pyqt5编写了一个程序。

该页面使用javascript呈现。

由于JavaScript需要花费一些时间来执行,因此我想确保页面已完全加载。

当前,我的程序检查页面中的值是否更改。

但是,IDLE重新启动。

问题是什么以及如何解决?

还有其他更好的方法来检查javascript是否完成吗?

import sys
from PyQt5 import QtCore, QtWidgets, QtWebEngineWidgets
from bs4 import BeautifulSoup

class Render(QtWebEngineWidgets.QWebEnginePage):
    def __init__(self, url):
        self.html = ""
        self.first_pass = True
        self.app = QtWidgets.QApplication(sys.argv)
        super(Render, self).__init__()
        self.loadFinished.connect(self._load_finished)
        self.loadProgress.connect(print)
        self.load(QtCore.QUrl(url))
        self.app.exec_()

    def _load_finished(self, result):
        if result:
            self.call_js()

    def call_js(self):
        self.runJavaScript('document.getElementById("txtDistance").value = "1";')
        self.runJavaScript("void(0)")
        self.runJavaScript("CheckUserWhere();")

######################## check value change #####################
        while True:
            self.toHtml(self.get_data)
            if BeautifulSoup(self.html, 'html.parser').find('div', {'id': 'MarketRules'}).find('span').text == '1':
                break
        self.toHtml(self.callable)

    def get_data(self, data):
        self.html = data
        print(self.html)

    def callable(self, data):
        self.html = data
        self.app.quit()

url = "https://land.3fang.com/LandAssessment/b6d8b2c8-bd4f-4bd4-9d22-ca49a7a2dc1f.html"
web = Render(url)
soup = BeautifulSoup(web.html, 'html.parser')
_bpgj = soup.find('b', {'id':"_bpgj"}).string
_bSumPrice = soup.find('b', {'id':"_bSumPrice"}).string
print(_bpgj, _bSumPrice)

出现错误:

0
22
70
js: A parser-blocking, cross site (i.e. different eTLD+1) script, https://api.map.baidu.com/getscript?v=1.3&ak=&services=&t=20181212032835, is invoked via document.write. The network request for this script MAY be blocked by the browser in this or a future page load due to poor network connectivity. If blocked in this page load, it will be confirmed in a subsequent console message. See https://www.chromestatus.com/feature/5718547946799104 for more details.
js: A parser-blocking, cross site (i.e. different eTLD+1) script, https://api.map.baidu.com/getscript?v=1.3&ak=&services=&t=20181212032835, is invoked via document.write. The network request for this script MAY be blocked by the browser in this or a future page load due to poor network connectivity. If blocked in this page load, it will be confirmed in a subsequent console message. See https://www.chromestatus.com/feature/5718547946799104 for more details.
js: Uncaught ReferenceError: SetTop is not defined
100

1 个答案:

答案 0 :(得分:0)

您不应在Qt中使用True时使用,因为它会锁定eventLoop,而应使用runJavaScript进行检查,并使用QEventLoop等待。

from functools import partial

# ...

class Render(QtWebEngineWidgets.QWebEnginePage):
    # ...

    def call_js(self):
        self.runJavaScript('document.getElementById("txtDistance").value = "1";')
        self.runJavaScript("void(0)")
        self.runJavaScript("CheckUserWhere();")
        self.wait()
        self.toHtml(self.callable)

    def wait(self):
        loop = QtCore.QEventLoop()
        _script = '''
            function task(){
                var element = document.getElementById("MarketRules");
                if (element == null)
                    return false;
                var tags = element.getElementsByTagName("span");
                for(i = 0; i < tags.length; i++)
                    if (tags[i].innerText == "1")
                        return true;
                return false;
            }
            task();
        '''
        def callback(result):
            if result:
                loop.quit()
            else:
                wrapper = partial(self.runJavaScript, _script, callback)
                QtCore.QTimer.singleShot(200, wrapper)
        self.runJavaScript(_script, callback)
        loop.exec_()

    # ...