Filling out a form using PyQt and QWebview

2019-02-07 05:20发布

问题:

I would like to use PyQt/QWebview to 1) load a specific url, 2) enter information into a form, 3) click buttons/links. Mechanize does not work because I need an actual browser.

Here's my code:

import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyQt4.QtWebKit import *
from PyQt4 import QtCore

app = QApplication(sys.argv)
web = QWebView()
web.load(QUrl("https://www.lendingclub.com/account/gotoLogin.action"))

def fillForm():
    doc = web.page().mainFrame().documentElement()
    user = doc.findFirst("input[id=master_username]")
    passwd = doc.findFirst("input[id=master_password]")

    user.setAttribute("value", "email@email.com")
    passwd.setAttribute("value", "password")


    button = doc.findFirst("input[id=master_sign-in-submit]")
    button.evaluateJavaScript("click()")

QtCore.QObject.connect(web, QtCore.SIGNAL("loadFinished"), fillForm)
web.show()
sys.exit(app.exec_())

The page loads correctly, but no input is entered and the form is not submitted. Any ideas?

回答1:

This helped me to make it work:

user.setAttribute("value", "email@email.com")
-->
user.evaluateJavaScript("this.value = 'email@email.com'")

Attribute and property are different things.

One more fix:

click() --> this.click()


回答2:

For anyone looking to do this with PyQt5, this example may help as several things have changed. Obviously the javascript needs to be adjusted based on the contents of the website.

import os
import sys
from PyQt5.QtWidgets import QApplication, QVBoxLayout, QWidget
from PyQt5.QtCore import QUrl, QEventLoop
from PyQt5.QtWebEngineWidgets import QWebEngineView

class WebPage(QWebEngineView):
    def __init__(self):
        QWebEngineView.__init__(self)
        self.load(QUrl("https://www.url.com"))
        self.loadFinished.connect(self._on_load_finished)

    def _on_load_finished(self):
        print("Finished Loading")
        self.page().toHtml(self.Callable)

    def Callable(self, html_str):
        self.html = html_str
        self.page().runJavaScript("document.getElementsByName('loginid')[0].value = 'email@email.com'")
        self.page().runJavaScript("document.getElementsByName('password')[0].value = 'test'")
        self.page().runJavaScript ("document.getElementById('signin').click()")

if __name__ == "__main__":
    app = QApplication(sys.argv)
    web = WebPage()
    web.show()
    sys.exit(app.exec_())  # only need one app, one running event loop


回答3:

You might be able to do it with Webkit/QWebView but what about using selenium: http://code.google.com/p/selenium/ ? It is designed for exactly this kind of browser automation and has nice python bindings.