Iteration einer For-Schleife wiederholen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Freddy19911
User
Beiträge: 9
Registriert: Montag 23. August 2021, 11:37

Hallo Zusammen,

ich habe mir ein paar Codezeilen zusammengeschrieben um mittels der Selenium Library auf eine Website zuzugreifen und das Herunterladen von Dokumenten zu automatisieren. Zu diesem Zweck iteriere ich mit Hilfe einer For-Schleife durch ein Dictionary. Meine Codestruktur sieht wie folgt aus:

Code: Alles auswählen

for key in mydict.keys():
    ein paar Zeilen Code
    for x in range(Number):
        ein paar Zeilen Code
    for x in range(Number):
        ein paar Zeilen Code
        
Wir ihr seht habe ich eine äußere For-Schleife mit der ich über das Dictionary iteriere sowie mehrere innere For-Schleifen, mit denen ich dann über eine bestimmte Range iteriere.
Nun kann es vorkommen, dass die Dateien unterschiedlich lange benötigen um heruntergeladen zu werden. Um den Abschluss des Downloads zu prüfen nutze ich aktuell folgende Funktion, die sowohl im äußeren als auch in den inneren For-Loops aufgerufen wird:

Code: Alles auswählen

def is_file_downloaded(filename, timeout=200):
    end_time = time.time() + timeout
    while not os.path.exists(filename):
        time.sleep(1)
        if time.time() > end_time:
            print("File not found within time")
            break
    if os.path.exists(filename):
        print("File found")
        return True
Die Funktion prüft also beim Aufruf 200 Sekunden lang ob der Dateipfad existiert. Ist dies der Fall, wird der Code weiter ausgeführt.

Es kommt leider auch vor, dass eine Datei während des Herunterladens nicht im Rahmen der vorgegebenen 200 Sekunden heruntergeladen ist und der Download quasi in einer Endlosschleife festhängt, also nicht beendet wird. Aktuell wird dann "File not found within time" ausgegeben und die Ausführung des Codes abgebrochen. Wenn ich dann eine neue Download Anfrage starte funktioniert der Download der Datei meist problemlos. Diese neue Anfrage würde ich nun gerne in meinem Code berücksichtigen, sodass ich sie nicht mehr manuell ausführen muss. Genauer gesagt suche ich nach einer Lösung, die es mir erlaubt den äußeren For-Loop bei einer Fehlermeldung erneut, d.h. mit derselben Iteration, zu durchlaufen. Nehmen wir an ich iteriere in dem äußeren For-Loop über das Alphabet. Wenn bei der Iteration beim Buchstaben D ein Fehler beim Download der Datei auftritt und die 200 Sekunden überschritten werden, soll der äußere For-Loop erneut gestartet werden und bei der Iteration bei D beginnen. Gibt es eine Möglichkeit diese erneute Schleifenbedingung direkt in der Download Funktion zu implementieren? Ich hatte überlegt anstatt des break Befehls in der Downloadfunktion einen Zähler einzubauen der entsprechend den Wert 1 annimmt, wenn der Download zu lange dauert und dann mittels einer while Schleife zu Beginn der äußeren For-Schleife zu prüfen, ob der Wert der Variable 1 entspricht. Nur bin ich mit der genauen Umsetzung überfordert und scheitere schon an der Problematik die äußere For-Schleife erneut bei der "fehlgeschlagenen" Iteration beginnen zu lassen.

Über Hilfe zu meinem Problem würde ich mich sehr freuen.

Vielen Dank und ein schönes Wochenende
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Alles was es dazu braucht ist eine while-Schleife, die so lange laeuft, bis die Datei eben da ist. Oder noch eine for-schleife, um zb nur x Versuche zu unternehmen. Die auessere Schleife ist davon nicht beruehrt, und die irgendwie wieder zu starten ist viel zu kompliziert gedacht.
Freddy19911
User
Beiträge: 9
Registriert: Montag 23. August 2021, 11:37

Vielen Dank für deine Antwort. Leider habe ich sie glaube ich nicht ganz verstanden. Ich möchte die in der Downloadfunktion definierten 200 Sekunden warten und nach Überschreitung die ganze äußere Schleife erneut starten, da somit dann eine neue Anfrage an den Server zum Download der entsprechenden Datei gestellt wird, die dann wiederum zum erfolgreichen Download führt. Kannst du mir verraten wo diese While-Schleife dann eingefügt werden muss, also ob im inneren der For-Schleife bspw.?
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Ja, die muss in die for-Schleife. Darum habe ich die ja als "aeussere schleife" bezeichnet.

Code: Alles auswählen

for i in range(1000):
    while True:
         if tu_etwas_mit_erfolg():
               break
Freddy19911
User
Beiträge: 9
Registriert: Montag 23. August 2021, 11:37

Nachdem ein Download fehlgeschlagen ist, d.h. die 200 Sekunden abgelaufen sind muss ich den Prozess des Seitenaufrufs allerdings neu durchlaufen (d.h. Aufruf, Login, Auswahl der Dateien etc.) damit der neue Downloadversuch funktioniert. Diese Schritte werden zu Beginn der äußeren For-Schleife gemacht und nicht wieder in den inneren For-Schleifen (sorry, diese Info hätte ich vermutlich in meinen Eingangspost erwähnen sollen). Vielleicht verstehe ich es auch falsch aber in deinem Codebeispiel hast du die While Schleife in eine der inneren For-Schleifen implementiert oder? Da ich den Prozess des Seitenaufrufs erneut durchlaufen muss, müsste ich eine While-Schleife aber in die äußere For-Schleife bauen oder?
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Wenn der Abruf der Seite in einer Funktion steht, kann man die beliebig oft und sehr einfach aufrufen.
Antworten