js:未捕获(承诺)null [PYQT5 QWebEnginePage]

js: Uncaught (in promise) null [PYQT5 QWebEnginePage]

我正在使用 PYQT5 创建一个验证码收割机,用于存储令牌并将它们传递到特定网站。问题是当我尝试用 js 函数存储它时,它 return 我这个错误:"js: Uncaught (in promise) null"

但是当我尝试 window.alert(grecaptcha.getResponse()) 时它起作用了,因此生成了令牌。 不幸的是我什至无法将它们保存在文本文件中

from PyQt5 import QtCore, QtGui, QtWidgets, QtWebEngineWidgets, QtWebChannel


class Backend(QtCore.QObject):
    valueChanged = QtCore.pyqtSignal(str)

    def __init__(self, parent=None):
        super().__init__(parent)
        self._value = ""

    @QtCore.pyqtProperty(str)
    def value(self):
        return self._value

    @value.setter
    def value(self, v):
        self._value = v
        self.valueChanged.emit(v)


class Widget(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.webEngineView = QtWebEngineWidgets.QWebEngineView()

        lay = QtWidgets.QVBoxLayout(self)
        lay.addWidget(self.webEngineView, stretch=1)

        backend = Backend(self)
        backend.valueChanged.connect(self.foo_function)
        self.channel = QtWebChannel.QWebChannel()
        self.channel.registerObject("backend", backend)
        self.webEngineView.page().setWebChannel(self.channel)
        self.webEngineView.page().setUrl(QtCore . QUrl("https://www.google.com/recaptcha/api2/demo"))
        self.webEngineView.page().setHtml("{}".format("""<html>

  <head>

    <title>Captcha Harvester</title>
    <style type="text/css">
      body {
        margin: 1em 5em 0 5em;
        font-family: sans-serif;
        background-color: #4D4746
      }
      p {
        font-family: sans-serif;
        color: #F3F0F0
      }
    </style>

  </head>

  <body>

    <p>CrepChef | Token Harvester</p>

    <div class="g-recaptcha" data-sitekey="6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-" data-callback="submitToken"></div>

    <p id="tokens">Available Tokens: 0</p>
    <p>Captcha Sitekey:  {{ sitekey }}</p>
    <p>Domain: {{ domain }}</p>

    <script type="text/javascript">
      function submitToken() {
        var backend = null;
        new QWebChannel(qt.webChannelTransport, function (channel) {
            backend = channel.objects.backend;
        });
        backend.value = grecaptcha.getResponse();
        grecaptcha.reset()
      }
    </script>

    <script type="text/javascript" src=static/scripts/jquery-3.2.1.min.js></script>
    <script type="text/javascript" src=static/scripts/captcha.js></script>
    <script type="text/javascript" src="https://www.google.com/recaptcha/api.js"></script>

  </body>

</html>
"""), baseUrl=QtCore.QUrl("https://www.google.com/recaptcha/api2/demo"))
        #path = "/test.html"
        #self.webEngineView.setUrl(QtCore.QUrl.fromLocalFile(path))

    @QtCore.pyqtSlot(str)
    def foo_function(self, value):
        print(value)


if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)
    w = Widget()
    w.show()
    sys.exit(app.exec_())

除了稍微重写你的逻辑外,我还删除了不必要的链接:

rom PyQt5 import QtCore, QtGui, QtWidgets, QtWebEngineWidgets, QtWebChannel


class Backend(QtCore.QObject):
    valueChanged = QtCore.pyqtSignal(str)

    def __init__(self, parent=None):
        super().__init__(parent)
        self._value = ""

    @QtCore.pyqtProperty(str, notify=valueChanged)
    def value(self):
        return self._value

    @value.setter
    def value(self, v):
        self._value = v
        self.valueChanged.emit(v)


HTML = """
<html>
   <head>
      <script src="qrc:///qtwebchannel/qwebchannel.js"></script>
      <title>Captcha Harvester</title>
      <style type="text/css">
         body {
         margin: 1em 5em 0 5em;
         font-family: sans-serif;
         background-color: #4D4746
         }
         p {
         font-family: sans-serif;
         color: #F3F0F0
         }
      </style>
      <script type="text/javascript">
         var backend = null;

          new QWebChannel(qt.webChannelTransport, function (channel) {
              backend = channel.objects.backend;
          });

         var verifyCallback = function(response) {
          backend.value = response;
         };
         var onloadCallback = function() {
          grecaptcha.render('example3', {
            'sitekey' : '6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-',
            'callback' : verifyCallback,
          });
         };
      </script>
   </head>
   <body>
      <p>CrepChef | Token Harvester</p>
      <div id="example3"></div>
      <p id="tokens">Available Tokens: 0</p>
      <p>Captcha Sitekey:  {{ sitekey }}</p>
      <p>Domain: {{ domain }}</p>
      <script src="https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=explicit" async defer></script>
   </body>
</html>
"""


class Widget(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.webEngineView = QtWebEngineWidgets.QWebEngineView()

        lay = QtWidgets.QVBoxLayout(self)
        lay.addWidget(self.webEngineView, stretch=1)

        backend = Backend(self)
        backend.valueChanged.connect(self.foo_function)
        self.channel = QtWebChannel.QWebChannel()
        self.channel.registerObject("backend", backend)
        self.webEngineView.page().setWebChannel(self.channel)
        self.webEngineView.page().setHtml(
            HTML, baseUrl=QtCore.QUrl("https://www.google.com/recaptcha/api2/demo"),
        )

    @QtCore.pyqtSlot(str)
    def foo_function(self, value):
        print(value)


if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)
    w = Widget()
    w.show()
    sys.exit(app.exec_())
``