Auswertung von Formularen mit CGI

Mit Hilfe von CGI lassen sich auch Webformulare auswerten. Das Formular kann dabei direkt in einer HTML-Datei stehen, es kann aber auch mit Hilfe einer Pythondatei durch CGI erzeugt werden. Dazu als erstes ein einfaches Beispiel:

Zunächst erstellen wir in unserem Webserver-Verzeichnis die folgende HTML-Datei mit einem Formular:

<!DOCTYPE html> <html lang="de"> <head> <meta charset="utf-8"> <title>Python - CGI-Programmierung</title> </head> <body> <form method='post' action='cgi-bin/script03_auswertung.py'> <p>Name: <input type='text' name='name' /></p> <p>Alter: <input type='text' name='alter' /></p> <input type='checkbox' name='happy' /> Happy <input type='checkbox' name='sad' /> Sad <input type='submit' name='submit' value='Submit' /> </form> </body> </html>

Neu ist das Attribut action im <form>-Tag. Es verweist auf das Script script03_auswertung.py, welches sich im Ordner cgi-bin befindet. Die Formulardaten werden nun als Werte von Variablen an dieses Script übermittelt. Das Script ist wie folgt aufgebaut:

#!/usr/bin/env python3 import cgi header = ''' <!DOCTYPE html> <html lang="de"> <head> <meta charset="utf-8"> <title>Python - CGI-Programmierung</title> </head> <body> ''' footer = ''' </body> </html> ''' form = cgi.FieldStorage() print(header) if form.getvalue("name"): name = form.getvalue("name") print("<h1>Hello " +name+"! Thanks for using my script!</h1><br />") if form.getvalue("alter"): alter = int(form.getvalue("alter")) print("<p>In ten years, you will be",alter+10,"years old.</p>") if form.getvalue("happy"): print("<p> Yayy! I'm happy too! </p>") if form.getvalue("sad"): print("<p> Oh no! Why are you sad? </p>") print(footer)

Im Auswertungsscript wird nun eine Webseite erzeugt, die die Formulardaten auswertet. Der wichtigste Befehl zum Auswerten des Formulars ist das Importieren der CGI-Bibliothek import cgi

Anschließend werden der Kopf- und der Fußquelltext der Seite als Variablen angelegt.

Danach wird mit dem Befehl form = cgi.FieldStorage() aus der Bibliothek cgider Inhalt des Formulars in der Variable form gespeichert.

Nun wird mit mehreren print-Anweisungen der Seitenquelltext in Abhängigkeit vom Formularinhalt ausgegeben. Dabei kann mit form.getvalue(...) auf die jeweiligen Formularelemente zugegriffen werden. Als Argument wird der Name des Formularelements übergeben. Die Funktion gibt eine Zeichenkette, das value des Formulars zurück. Falls es kein value gibt, wird None zurückgegeben.

Aufgabe 1

Teste die Scripte. Lass dir weitere Formularelemente einfallen, die du dann auswertest.

Das Ganze kann man auch in einer Datei zusammenfassen:

#!/usr/bin/env python3 import cgi header = ''' <!DOCTYPE html> <html lang="de"> <head> <meta charset="utf-8"> <title>Python - CGI-Programmierung</title> </head> <body> ''' footer = ''' </body> </html> ''' form = cgi.FieldStorage() print(header) if form.getvalue("submit"): if form.getvalue("name"): name = form.getvalue("name") print("<h1>Hello " +name+"! Thanks for using my script!</h1><br />") if form.getvalue("alter"): alter = int(form.getvalue("alter")) print("<p>In ten years, you will be",alter+10,"years old.</p>") if form.getvalue("happy"): print("<p> Yayy! I'm happy too! </p>") if form.getvalue("sad"): print("<p> Oh no! Why are you sad? </p>") else: print("<form method='post' action='script04.py'>") print("<p>Name: <input type='text' name='name' /></p>") print("<p>Alter: <input type='text' name='alter' /></p>") print("<input type='checkbox' name='happy' /> Happy") print("<input type='checkbox' name='sad' /> Sad") print("<input type='submit' name='submit' value='Submit' />") print("</form>") print(footer)

Wie funktioniert nun dieses Script?

Im Prinzip ist der Aufbau ähnlich wie bei script03_auswertung.py. Der Unterschied ist, dass zunächst mit der if-Anweisung getestet wird, ob im Formularelement „submit“ der Wert „Submit“ übermittelt worden ist. Wenn das nicht der Fall ist, gab es noch kein Formular, welches ausgewertet werden konnte und nun wird im else-Zweig das Formular ausgegeben. Wenn ein Wert existiert, gab es ein Formular, welches ausgewertet wird (if-Zweig).

Aufgabe 2

Schreibe dein geändertes Script so um, dass es in einer Datei funktioniert.

Ein komplexes Beispiel für ein Kopfrechenprogramm:

#!/usr/bin/env python3 import cgi, cgitb, random cgitb.enable() header = ''' <!DOCTYPE html> <html lang="de"> <head> <meta charset="utf-8"> <title>Python - CGI-Programmierung</title> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-aFq/bzH65dt+w6FI2ooMVUpc+21e0SRygnTpmBvdBgSdnuTN7QbdgL+OapgHtvPp" crossorigin="anonymous"> </head> <body> <div class="container"> ''' footer = ''' </div> </body> </html> ''' form = cgi.FieldStorage() print(header) print("<p></p><h1>Kopfrechnen</h1>") if form.getvalue("config"): ro = form.getvalue("ro") anz = int(form.getvalue("anz")) opmin1 = int(form.getvalue("opmin1")) opmax1 = int(form.getvalue("opmax1")) opmin2 = int(form.getvalue("opmin2")) opmax2 = int(form.getvalue("opmax2")) print("<form method='post' action='script06.py'>") print("<input type='hidden' name='ro' value = '"+str(ro)+"' />") print("<input type='hidden' name='anz' value = '"+str(anz)+"' />") if ro == 'Addition': print("<h2>Addition</h2>") for i in range(anz): a = random.randint(opmin1,opmax1) b = random.randint(opmin2,opmax2) print("<p>"+str(i+1)+". Aufgabe : "+str(a)+" + "+str(b)+" = <input type='text' name='ergebnis"+str(i+1)+"' /></p>") print("<input type='hidden' name='a"+str(i+1)+"' value = '"+str(a)+"' />") print("<input type='hidden' name='b"+str(i+1)+"' value = '"+str(b)+"' />") elif ro == 'Subtraktion': print("<h2>Subtraktion</h2>") for i in range(anz): while(True): a = random.randint(opmin1,opmax1) b = random.randint(opmin2,opmax2) if a>b: break print("<p>"+str(i+1)+". Aufgabe : "+str(a)+" - "+str(b)+" = <input type='text' name='ergebnis"+str(i+1)+"' /></p>") print("<input type='hidden' name='a"+str(i+1)+"' value = '"+str(a)+"' />") print("<input type='hidden' name='b"+str(i+1)+"' value = '"+str(b)+"' />") elif ro == 'Multiplikation': print("<h2>Multiplikation</h2>") for i in range(anz): a = random.randint(opmin1,opmax1) b = random.randint(opmin2,opmax2) print("<p>"+str(i+1)+". Aufgabe : "+str(a)+" * "+str(b)+" = <input type='text' name='ergebnis"+str(i+1)+"' /></p>") print("<input type='hidden' name='a"+str(i+1)+"' value = '"+str(a)+"' />") print("<input type='hidden' name='b"+str(i+1)+"' value = '"+str(b)+"' />") elif ro == 'Division': print("<h2>Division</h2>") for i in range(anz): while(True): a = random.randint(opmin1,opmax1) b = random.randint(opmin2,opmax2) if a > b and a%b == 0 and b > 1: break print("<p>"+str(i+1)+". Aufgabe : "+str(a)+" : "+str(b)+" = <input type='text' name='ergebnis"+str(i+1)+"' /></p>") print("<input type='hidden' name='a"+str(i+1)+"' value = '"+str(a)+"' />") print("<input type='hidden' name='b"+str(i+1)+"' value = '"+str(b)+"' />") print("<p><button name='submit' value='True' >Absenden!</button></p>") print("</form") elif form.getvalue("submit"): ro = form.getvalue("ro") anz = int(form.getvalue("anz")) if ro == 'Addition': print("<h2>Addition</h2>") for i in range(anz): if form.getvalue("ergebnis"+str(i+1)): e = int(form.getvalue("ergebnis"+str(i+1))) else: e = None a = int(form.getvalue("a"+str(i+1))) b = int(form.getvalue("b"+str(i+1))) if e == None: print("<p>",a,"+",b,"= - Ergebnis wurde nicht eingegeben! Richtiges Ergebnis:",a+b,"</p>") else: if e == a+b: print("<p>",a,"+",b,"=",e,"Richtig!</p>") else: print("<p>",a,"+",b,"=",e,"Falsch! Richtiges Ergebnis:",a+b,"</p>") elif ro == 'Subtraktion': print("<h2>Subtraktion</h2>") for i in range(anz): if form.getvalue("ergebnis"+str(i+1)): e = int(form.getvalue("ergebnis"+str(i+1))) else: e = None a = int(form.getvalue("a"+str(i+1))) b = int(form.getvalue("b"+str(i+1))) if e == None: print("<p>",a,"-",b,"= - Ergebnis wurde nicht eingegeben! Richtiges Ergebnis:",a-b,"</p>") else: if e == a-b: print("<p>",a,"-",b,"=",e,"Richtig!</p>") else: print("<p>",a,"-",b,"=",e,"Falsch! Richtiges Ergebnis:",a-b,"</p>") elif ro == 'Multiplikation': print("<h2>Multiplikation</h2>") for i in range(anz): if form.getvalue("ergebnis"+str(i+1)): e = int(form.getvalue("ergebnis"+str(i+1))) else: e = None a = int(form.getvalue("a"+str(i+1))) b = int(form.getvalue("b"+str(i+1))) if e == None: print("<p>",a,"*",b,"= - Ergebnis wurde nicht eingegeben! Richtiges Ergebnis:",a*b,"</p>") else: if e == a*b: print("<p>",a,"*",b,"=",e,"Richtig!</p>") else: print("<p>",a,"*",b,"=",e,"Falsch! Richtiges Ergebnis:",a*b,"</p>") elif ro == 'Division': print("<h2>Division</h2>") for i in range(anz): if form.getvalue("ergebnis"+str(i+1)): e = int(form.getvalue("ergebnis"+str(i+1))) else: e = None a = int(form.getvalue("a"+str(i+1))) b = int(form.getvalue("b"+str(i+1))) if e == None: print("<p>",a,":",b,"= - Ergebnis wurde nicht eingegeben! Richtiges Ergebnis:",a//b,"</p>") else: if e == a//b: print("<p>",a,":",b,"=",e,"Richtig!</p>") else: print("<p>",a,":",b,"=",e,"Falsch! Richtiges Ergebnis:",a//b,"</p>") print("<form method='post' action='script06.py'>") print("<p><button name='neu' value='True' >Neu Starten!</button></p>") print("</form>") else: print("<h3>Konfiguration</h3>") print("<form method='post' action='script06.py'>") print(""" <p>Wähle die Rechennoperation!</p> <fieldset> <input type="radio" id="add" name="ro" value="Addition"> <label for="add"> Addition</label><br> <input type="radio" id="sub" name="ro" value="Subtraktion"> <label for="sub"> Subtraktion</label><br> <input type="radio" id="mult" name="ro" value="Multiplikation"> <label for="mult"> Multiplikation</label><br> <input type="radio" id="div" name="ro" value="Division"> <label for="division"> Division</label><br> </fieldset> <p></p> <p>Wie viele Aufgaben?</p> <p> <select name="anz"> <option>10</option> <option>15</option> <option>20</option> <option>25</option> <option>30</option> </select> <p>In welchem Bereich sollen die Operanden liegen?</p> <table> <tr><td></td><td>Minimum</td><td>Maximum</td></tr> <tr><td>1. Operant</td><td><input name="opmin1" type="number" min="0" max="100" value="1"/></td><td><input name="opmax1" type="number" min="0" max="100" value="10"/></td></tr> <tr><td>2. Operant</td><td><input name="opmin2" type="number" min="0" max="100" value="1"/></td><td><input name="opmax2" type="number" min="0" max="100" value="10"/></td></tr> </table> </p> """) print("<p><button name='config' value='True' >Konfigurieren!</button></p>") print("</form") print(footer)

Aufgabe3

Teste das Script und versuche den Quelltext zu verstehen! Versuche ein ähnliches Programm mit anderen Aufgabeentypen zu schreiben.