Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Filling out a form using PyQt and QWebview

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 protected]")
    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?

like image 848
user1137778 Avatar asked Jun 16 '12 03:06

user1137778


2 Answers

This helped me to make it work:

user.setAttribute("value", "[email protected]")
-->
user.evaluateJavaScript("this.value = '[email protected]'")

Attribute and property are different things.

One more fix:

click() --> this.click()
like image 149
Denis Ryzhkov Avatar answered Oct 20 '22 05:10

Denis Ryzhkov


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 protected]'")
        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
like image 29
aoh Avatar answered Oct 20 '22 04:10

aoh