From 89d3d479b495d28c59a759d066842828c7825506 Mon Sep 17 00:00:00 2001 From: Simon Date: Wed, 26 May 2021 18:26:06 +0200 Subject: [PATCH] Save screenshots and html when selenium error --- tools/its.py | 66 +++++++++++++++++++++++++++++++++------------------- 1 file changed, 42 insertions(+), 24 deletions(-) diff --git a/tools/its.py b/tools/its.py index d864a39f..066c6eaa 100644 --- a/tools/its.py +++ b/tools/its.py @@ -22,12 +22,14 @@ try: import beepy + ENABLE_BEEPY = True except ImportError: ENABLE_BEEPY = False + class ImpfterminService(): - def __init__(self, code: str, plz_impfzentren: list, kontakt: dict,PATH:str): + def __init__(self, code: str, plz_impfzentren: list, kontakt: dict, PATH: str): self.code = str(code).upper() self.splitted_code = self.code.split("-") @@ -151,7 +153,6 @@ def impfstoffe_laden(self): self.log.error("Keine Impfstoffe im ausgewählten Impfzentrum verfügbar") return False - def get_chromedriver_path(self): """ :return: String mit Pfad zur chromedriver-Programmdatei @@ -176,7 +177,6 @@ def get_chromedriver_path(self): else: raise ValueError(f"Nicht unterstütztes Betriebssystem {self.operating_system}") - def get_chromedriver(self, headless): chrome_options = Options() @@ -194,7 +194,6 @@ def get_chromedriver(self, headless): return Chrome(self.get_chromedriver_path(), options=chrome_options) - def driver_enter_code(self, driver, plz_impfzentrum): """ TODO xpath code auslagern @@ -224,7 +223,7 @@ def driver_enter_code(self, driver, plz_impfzentrum): # Klick auf "Vermittlungscode bereits vorhanden" button_xpath = "/html/body/app-root/div/app-page-its-login/div/div/div[2]/app-its-login-user/" \ - "div/div/app-corona-vaccination/div[2]/div/div/label[1]/span" + "div/div/app-corona-vaccination/div[2]/div/div/label[1]/span" button = WebDriverWait(driver, 1).until( EC.element_to_be_clickable((By.XPATH, button_xpath))) action = ActionChains(driver) @@ -232,8 +231,8 @@ def driver_enter_code(self, driver, plz_impfzentrum): # Auswahl des ersten Code-Input-Feldes input_xpath = "/html/body/app-root/div/app-page-its-login/div/div/div[2]/app-its-login-user/" \ - "div/div/app-corona-vaccination/div[3]/div/div/div/div[1]/app-corona-vaccination-yes/" \ - "form[1]/div[1]/label/app-ets-input-code/div/div[1]/label/input" + "div/div/app-corona-vaccination/div[3]/div/div/div/div[1]/app-corona-vaccination-yes/" \ + "form[1]/div[1]/label/app-ets-input-code/div/div[1]/label/input" input_field = WebDriverWait(driver, 1).until( EC.element_to_be_clickable((By.XPATH, input_xpath))) action = ActionChains(driver) @@ -245,8 +244,8 @@ def driver_enter_code(self, driver, plz_impfzentrum): # Klick auf "Termin suchen" button_xpath = "/html/body/app-root/div/app-page-its-login/div/div/div[2]/app-its-login-user/" \ - "div/div/app-corona-vaccination/div[3]/div/div/div/div[1]/app-corona-vaccination-yes/" \ - "form[1]/div[2]/button" + "div/div/app-corona-vaccination/div[3]/div/div/div/div[1]/app-corona-vaccination-yes/" \ + "form[1]/div[2]/button" button = WebDriverWait(driver, 1).until( EC.element_to_be_clickable((By.XPATH, button_xpath))) action = ActionChains(driver) @@ -255,7 +254,6 @@ def driver_enter_code(self, driver, plz_impfzentrum): # Maus-Bewegung hinzufügen (nicht sichtbar) action.move_by_offset(10, 20).perform() - def driver_renew_cookies(self, driver, plz_impfzentrum): self.driver_enter_code(driver, plz_impfzentrum) @@ -273,9 +271,8 @@ def driver_renew_cookies(self, driver, plz_impfzentrum): except: return False - - def driver_book_appointment(self, driver, plz_impfzentrum): + PATH = os.path.dirname(os.path.realpath(__file__)) url = f"{self.domain}impftermine/service?plz={plz_impfzentrum}" self.driver_enter_code(driver, plz_impfzentrum) @@ -287,13 +284,20 @@ def driver_book_appointment(self, driver, plz_impfzentrum): EC.element_to_be_clickable((By.XPATH, button_xpath))) action = ActionChains(driver) action.move_to_element(button).click().perform() - time.sleep(.5) except: self.log.error("Termine können nicht gesucht werden") + try: + filepath = os.path.join(PATH, "log/errorterminsuche/") + timestamp = str(datetime.datetime.now()).replace(":", "").split(".")[0] + driver.get_screenshot_as_file(filepath + "errorterminsuche" + timestamp + ".jpg") + except: + self.log.error("Screenshot konnte nicht gespeichert werden") + pass pass # Termin auswählen try: + time.sleep(3) button_xpath = '//*[@id="itsSearchAppointmentsModal"]/div/div/div[2]/div/div/form/div[1]/div[2]/label/div[2]/div' button = WebDriverWait(driver, 1).until( EC.element_to_be_clickable((By.XPATH, button_xpath))) @@ -302,9 +306,18 @@ def driver_book_appointment(self, driver, plz_impfzentrum): time.sleep(.5) except: self.log.error("Termine können nicht ausgewählt werden") + try: + PATH = os.path.dirname(os.path.realpath(__file__)) + filepath = os.path.join(PATH, "log/errorterminauswahl/") + timestamp = str(datetime.datetime.now()).replace(":", "").split(".")[0] + with open(filepath + "errorterminauswahl" + timestamp + ".html", 'w', encoding='utf-8') as file: + file.write(str(driver.page_source)) + driver.get_screenshot_as_file(filepath + "errorterminauswahl" + timestamp + ".jpg") + except: + self.log.error("HTML und Screenshot konnten nicht gespeichert werden") + pass pass - # Klick Button "AUSWÄHLEN" try: button_xpath = '//*[@id="itsSearchAppointmentsModal"]/div/div/div[2]/div/div/form/div[2]/button[1]' @@ -384,6 +397,13 @@ def driver_book_appointment(self, driver, plz_impfzentrum): input_field.send_keys(self.kontakt['notificationReceiver']) except: self.log.error("Kontaktdaten können nicht eingegeben werden") + try: + filepath = os.path.join(PATH, "log/errordateneingeben/") + timestamp = str(datetime.datetime.now()).replace(":", "").split(".")[0] + driver.get_screenshot_as_file(filepath + "errordateneingeben" + timestamp + ".jpg") + except: + self.log.error("Screenshot konnte nicht gespeichert werden") + pass pass # Klick Button "ÜBERNEHMEN" @@ -412,15 +432,15 @@ def driver_book_appointment(self, driver, plz_impfzentrum): if "Ihr Termin am" in str(driver.page_source): msg = "Termin erfolgreich gebucht!" self.log.success(msg) - desktop_notification(operating_system=self.operating_system,title="Terminbuchung:",message=msg) + desktop_notification(operating_system=self.operating_system, title="Terminbuchung:", message=msg) return True else: - self.log.error("Automatisierte Terminbuchung fehlgeschlagen. Termin manuell im Fenster oder im Browser buchen.") + self.log.error( + "Automatisierte Terminbuchung fehlgeschlagen. Termin manuell im Fenster oder im Browser buchen.") print("Link für manuelle Buchung im Browser:", url) - time.sleep(10*60) + time.sleep(10 * 60) return False - @retry_on_failure() def renew_cookies(self): """ @@ -432,7 +452,6 @@ def renew_cookies(self): with self.get_chromedriver(headless=True) as driver: return self.driver_renew_cookies(driver, choice(self.plz_impfzentren)) - @retry_on_failure() def book_appointment(self): """ @@ -479,7 +498,6 @@ def login(self): else: return False - @retry_on_failure() def termin_suchen(self, plz): """Es wird nach einen verfügbaren Termin in der gewünschten PLZ gesucht. @@ -560,7 +578,7 @@ def termin_buchen(self): if res.status_code == 201: msg = "Termin erfolgreich gebucht!" self.log.success(msg) - desktop_notification(operating_system=self.operating_system,title="Terminbuchung:",message=msg) + desktop_notification(operating_system=self.operating_system, title="Terminbuchung:", message=msg) return True elif res.status_code == 429: @@ -579,7 +597,7 @@ def termin_buchen(self): msg = f"Unbekannter Statuscode: {res.status_code}" self.log.error(msg) - desktop_notification(operating_system=self.operating_system,title="Terminbuchung:", message=msg) + desktop_notification(operating_system=self.operating_system, title="Terminbuchung:", message=msg) return False @retry_on_failure() @@ -650,7 +668,7 @@ def code_bestaetigen(self, token, sms_pin): return False @staticmethod - def terminsuche(code: str, plz_impfzentren: list, kontakt: dict,PATH:str, check_delay: int = 30): + def terminsuche(code: str, plz_impfzentren: list, kontakt: dict, PATH: str, check_delay: int = 30): """ Workflow für die Terminbuchung. @@ -661,7 +679,7 @@ def terminsuche(code: str, plz_impfzentren: list, kontakt: dict,PATH:str, check_ :return: """ - its = ImpfterminService(code, plz_impfzentren, kontakt,PATH) + its = ImpfterminService(code, plz_impfzentren, kontakt, PATH) its.renew_cookies() # login ist nicht zwingend erforderlich