我需要获取动态内容,该内容正在由ajax js调用加载。
我真的不知道如何使用PyQt,但我希望可以做到这一点。 HTML类似于:
<a href="#" id="id" onclick="A4J.AJAX.Submit('j_id0:j_id1:j_id110',event,{'similarityGroupingId':'j_id0:j_id1:j_id110:j_id582:0:j_id584'});return false;">NETHERLANDS</a>`
我可以使用以下简单代码使用PyQt渲染页面:
def render(source_html):
import sys
from PyQt5.QtCore import QEventLoop
from PyQt5.QtWidgets import QApplication
from PyQt5.QtWebEngineWidgets import QWebEngineView
class Render(QWebEngineView):
def __init__(self, html):
self.html = None
self.app = QApplication(sys.argv)
QWebEngineView.__init__(self)
self.loadFinished.connect(self._loadFinished)
self.setHtml(html)
while self.html is None:
self.app.processEvents(QEventLoop.ExcludeUserInputEvents | QEventLoop.ExcludeSocketNotifiers | QEventLoop.WaitForMoreEvents)
self.app.quit()
def _callable(self, data):
self.html = data
def _loadFinished(self, result):
self.page().toHtml(self._callable)
return Render(source_html).html
import requests
sample_html = requests.get('https://riverbankcomputing.com/software/pyqt/').text
print(render(sample_html))
我如何运行该“ onclick”并获取内容?
这是一个老问题,但是...
要从javascript运行PyQt函数:
[虽然可能有很多方法,但我已经通过使用QWebChannel
解决了这一问题,然后从您的html调用js函数,然后使用网络渠道与Qt进行通信。
您将需要qwebchannel.js
。我是从本地计算机上的Qt5示例目录获得的。网路上的许多地方都有相同的档案。我会让你找它。
这里描述了很多这种方法:http://doc.qt.io/qt-5/qtwebchannel-javascript.html
在您的__init__
中,创建一个网络频道:
self.webchannel = QtWebChannel.QWebChannel(self)
然后将您的webengineview的主页设置为使用频道,并注册要在PyQt和js之间共享的对象:
self.page().setWebChannel(self.webchannel)
self.webchannel.registerObject('MyChannel', self)
在您的.js(或.html的javascript部分中,设置网络频道:
var MyChannel = null;
new QWebChannel(qt.webChannelTransport, function(channel) {
MyChannel = channel.objects.MyChannel;
});
((qwebchannel.js
发挥作用。您的js或html文件必须能够包含它。对我来说,我在执行其他js之前先加载了<script src="scripts/qwebchannel.js"></script>
现在您已设置为通过通道从js到PyQt进行调用,但是您可以调用什么呢?任何装饰为PyQt插槽的东西。因此,例如,如果您想在javascript中调用Render中的“ foo”函数,该函数将字符串作为参数,则可以这样创建它(作为Render的成员):
@QtCore.pyqtSlot(str)
def foo(self, some_tring):
print ("Some string: %s" % some_string)
...,然后在js文件中(或在index.html中),您只需调用MyChannel.foo('whatever')
。您可以将其作为onclick,也可以从onclick调用的另一个函数的主体中进行。
通过MyChannel.foo('whatever')
对话:之所以调用MyChannel
,是因为这是您分配给在通道中注册的对象的名称(在python中),也是在创建new QWebChannel
时在js中使用的名称。创建注册时,将self
作为要注册的对象-因此,由MyChannel
标识的通道是Render
对象。您只能通过该通道发出信号,因此您“呼叫”的任何内容都必须是插槽-因此是装饰器。
或者,如果您想从PyQt调用js函数,则要容易一些。在这种情况下,您只需致电
self.page().runJavaScript('someJsFunction("whatever");')
如果您需要对响应做出某种处理,因为它被称为异步,则需要设置响应处理程序:
self.page().runJavaScript('someJsFunction("whatever");', self.__callback)
...然后定义回调(可能是Render的成员):
def __callback(self, response):
if response:
print ("Handling JS response: %s", response)