Immer wieder ist es notwendig Daten auf Webseiten einzugeben, oder für SuS. bei manchen Diensten Accounts anzulegen.

Wenn die Webseite z.B. keinen CSV-Upload unterstützt oder keine API anbietet, kann dies schnell in Arbeit ausarten und sehr mühsam sein. Bestes Beispiel hierfür ist Sokrates – für Schulen gibt es keine API um Schülerdaten zu aktualisieren. Mittlerweile gibt es wenigstens einen CSV-Upload.

Hier kommt Selenium Webdriver ins Spiel. WebDriver ist die entscheidende Schnittstelle für die Simulation von Nutzerinteraktionen in jedem beliebigen Browser – ob Firefox, Chrome, Edge, Safari. Seit 2018 ist die API ein offizieller W3C-Standard.

WebDriver steuert einen Browser nativ, so wie es ein Benutzer tun würde, entweder lokal oder auf einem entfernten Rechner mit Hilfe des Selenium-Servers, was einen großen Fortschritt in Bezug auf die Browserautomatisierung darstellt.

Am Beispiel von at4.typewriter.at habe ich ein Python Skript erstellt, das Benutzer aus einer CSV-Datei ausliest und diese dort automatisiert anlegt. Die Programmiersprache selbst ist aber egal. Webdriver gibt es offiziell für Java, Python, JavaScript, C# und Ruby, aber auch ein paar inoffizielle wie PHP, R, oder Dart.

Die Installation ist relativ einfach. Folgende Befehle sind dazu notwendig.

apt install python3 python3-pip
pip install selenium

Und so sieht das Programm dann aus.

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
import time
import csv
import sys


def login():
   driver.get("https://at4.typewriter.at/index.php")
   driver.find_element(By.ID,"LoginForm_username").send_keys("LOGIN")
   driver.find_element(By.ID,"LoginForm_pw").send_keys("PASSWORD")
   driver.find_element_by_name("yt0").click()
   time.sleep(5)
   
def findFormInOverviewList(form):
   driver.get("https://at4.typewriter.at/index.php?r=group/groupsOverview")
   time.sleep(1)
   formLink = driver.find_element(By.XPATH,"//td[text()='"+form+"']/parent::tr/td[4]/a[@title='Klassenliste anzeigen!']")
   formLink.click()
   time.sleep(1)

   
def readCSV():
   with open(filename) as csvdatei:
      csv_reader_object = csv.reader(csvdatei,delimiter=",")
      next(csv_reader_object, None) #Skip header
      for row in csv_reader_object:
         addUser(row[0],row[1],row[3])

def addUser(firstname,lastname,login):
    driver.find_element(By.ID, "CreatePupilInPupillistFormModel_username").send_keys(login)
    driver.find_element(By.ID, "CreatePupilInPupillistFormModel_forename").send_keys(firstname)
    driver.find_element(By.ID, "CreatePupilInPupillistFormModel_surename").send_keys(lastname)
    driver.find_element_by_name("yt1").click()
    time.sleep(1)


def main():
    filename = ''
    form =''
    n = len(sys.argv)    
    if (n != 3):
       print(" Bitte folgende Argumente übergeben: Dateiname, Klasse")
       sys.exit()
    else:
       filename = sys.argv[1]
       form = sys.argv[2]
    login()
    findFormInOverviewList(form)
    readCSV()
    driver.close()
 
driver = webdriver.Firefox()   
main()

Das Programm ruft man mit 2 zusätzlichen Parametern, CSV-Datei und den Namen der Klasse aus der Klassenübersicht auf. Bsp.:

python3 createUser 4B.csv 4B

In der main() Methode, die ganz unten aufgerufen wird, lesen wir die 2 Parameter aus. Fehlt ein Parameter, wird eine Fehlermeldung ausgegeben und das Programm beendet.

Anschließend loggen wir uns ein. Dazu öffnen wir die Startseite unserer Webapplikation. Füllen das Formular aus – das geht in diesem Fall sehr einfach, weil die Formularelemente Login (LoginForm_username) und Passwort (LoginForm_pw) per id direkt angesprochen werden können. Abschließend klicken wir noch auf den Login-Button, der den Namen „yt0“ hat.

Vielleicht stellen sich manche die Frage, wie man die Ids bzw. den Namen „yt0“ herausfindet. Dazu öffnet man die Webseite mit Firefox oder Google-Chrome und klickt anschließend „F12“. Dadurch öffnen sich die Webdeveloper-Tools. Damit kann man jedes HTML-Element analysieren und findet so z.B. die Ids oder den Namen des Login-Buttons.

Nachdem das Einloggen etwas dauern kann, warten wir ein paar Sekunden. Nach dem Login wechseln wir auf die Klassenübersicht und suchen dort die angegebene Klasse. Zur Klassenübersicht gelangt man über die fixe URL „https://at4.typewriter.at/index.php?r=group/groupsOverview“.

In dieser Übersicht müssen wir jetzt die Zeile mit unserer Klasse finden. Dazu verwenden wir einen sogannten XPath-Locator. Den richtigen Locator zu finden ist nicht immer ganz einfach. Hier gibt es dazu weitere Informationen.

Unser XPath sieht so aus: „//td[text()='“+form+“‚]/parent::tr/td[4]/a[@title=’Klassenliste anzeigen!‘]

Wir sagen Webdriver damit also, suche eine Spalte mit dem Text „4B“ und weiter zum (parent) Zeilenelement tr, und dort die 4 Spalte in der es einen Link mit dem Titel „Klasseliste anzeigen“ gibt.
Auf das gefundene Element klicken wir.

Den XPath kann man auch mit den Developer-Tools finden, indem man ein HTML-Element auswählt, anschließend einen rechten Mausklick auf Kopieren und dort dann XPath auswählt. Leider hilft das nur beschränkt, weil das immer der absolute Pfad aus der aktuellen Ansicht ist.

In der Console kann man den XPath auch testen, indem man $x(„//td[text()=’4F‘]“) ausführt.

Nach etwas Einarbeitungszeit findet man sich aber doch schnell zurecht. Wichtig dabei ist, dass es immer mehrere Wege zum Ziel für den richtigen XPath-Ausdruck gibt. So finden wir unseren Link auch mit dem Ausdruck „//*[text()=’4B‘]//following-sibling::td[3]/a[1]“

Nach dem Klick auf das gefundene Element, sehen wir einerseits die Liste der SuS. in der Klasse falls schon welche vorhanden sind, und darunter das Formular, das wir befüllen wollen.

Einmal mehr verwenden wir die Developer-Tools, um die Ids für das Formular und den Namen des Erstellen-Buttons zu finden. Damit können wir die Methode addUser() erstellen.

Jetzt lesen wir noch die CSV-Datei aus und rufen darin für jede Zeile die Methode addUser(row[0],row[1],row[3]) auf.
Das CSV-File lade ich mir einfach von einem Moodle-Kurs herunter. Dazu im Kurs auf Teilnehmer klicken, die gewünschten Teilnehmer auswählen und unten auf „Komma separierte Werte (.csv)“ klicken. Diese Datei enthält eine Header-Zeile, diese wird mit next(sv_reader_object, None) ignoriert.

Webdriver kann man auch sehr gut zum Cross-Browser-Testen einer Webapplikation verwenden.

Weitere Infos zu Webdriver findet man unter:

https://www.selenium.dev/de/documentation/webdriver/ oder

in diesem Buch

Kategorien: HowToSoftwareTools

0 Kommentare

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert