From 88d7b3c2a9ef3d7fcb139cf77c476a1fca125dee Mon Sep 17 00:00:00 2001 From: CHUN YU YAO Date: Fri, 13 Jan 2023 06:29:58 +0800 Subject: [PATCH] 2023-01-13, allow submit wrong captcha code. --- chrome_tixcraft.py | 106 +++++++++++++++++++++++++++++++++------------ settings.json | 2 +- settings.py | 51 ++++++++++++++++++++-- 3 files changed, 128 insertions(+), 31 deletions(-) diff --git a/chrome_tixcraft.py b/chrome_tixcraft.py index 7385440..a6fb4da 100644 --- a/chrome_tixcraft.py +++ b/chrome_tixcraft.py @@ -1389,7 +1389,8 @@ def tixcraft_ticket_agree(driver): try: # TODO: check the status: checked. if form_checkbox.is_enabled(): - form_checkbox.click() + if not form_checkbox.is_selected(): + form_checkbox.click() is_finish_checkbox_click = True except Exception as exc: print("click TicketForm_agree fail") @@ -1617,8 +1618,9 @@ def tixcraft_toast(driver, message): except Exception as exc: print("find toast element fail") -def tixcraft_manully_keyin_verify_code(driver, answer = "", auto_submit = False): +def tixcraft_keyin_captcha_code(driver, answer = "", auto_submit = False): is_verifyCode_editing = False + is_form_sumbited = False # manually keyin verify code. # start to input verify code. @@ -1639,14 +1641,6 @@ def tixcraft_manully_keyin_verify_code(driver, answer = "", auto_submit = False) if is_visible: try: form_verifyCode.click() - #print("start to fill answer.") - form_verifyCode.send_keys(answer) - if auto_submit: - form_verifyCode.send_keys(Keys.ENTER) - else: - driver.execute_script("document.getElementById(\"TicketForm_verifyCode\").select();") - tixcraft_toast(driver, "※ Press Enter if answer is: " + answer) - is_verifyCode_editing = True except Exception as exc: print("click form_verifyCode fail, tring to use javascript.") @@ -1655,15 +1649,48 @@ def tixcraft_manully_keyin_verify_code(driver, answer = "", auto_submit = False) driver.execute_script("document.getElementById(\"TicketForm_verifyCode\").focus();") is_verifyCode_editing = True except Exception as exc: - print("click form_verifyCode fail") - pass - pass - return is_verifyCode_editing + print("click form_verifyCode fail.") + + #print("start to fill answer.") + try: + if len(answer) > 0: + form_verifyCode.send_keys(answer) + if auto_submit: + form_verifyCode.send_keys(Keys.ENTER) + is_verifyCode_editing = False + is_form_sumbited = True + else: + driver.execute_script("document.getElementById(\"TicketForm_verifyCode\").select();") + if len(answer) > 0: + tixcraft_toast(driver, "※ 按 Enter 如果答案是: " + answer) + except Exception as exc: + print("send_keys ocr answer fail.") + + return is_verifyCode_editing, is_form_sumbited + +def tixcraft_reload_captcha(driver): + # manually keyin verify code. + # start to input verify code. + ret = False + form_captcha = None + try: + form_captcha = driver.find_element(By.ID, 'yw0') + if not form_captcha is None: + form_captcha.click() + ret = True + except Exception as exc: + print("find form_captcha fail") + + return ret #PS: credit to LinShihJhang's share -def tixcraft_auto_ocr(driver, ocr, ocr_captcha_with_submit): +def tixcraft_auto_ocr(driver, ocr, ocr_captcha_with_submit, ocr_captcha_force_submit, previous_answer): print("start to ddddocr") + is_need_redo_ocr = False + is_form_sumbited = False + orc_answer = None + if not ocr is None: try: form_verifyCode_base64 = driver.execute_async_script(""" @@ -1685,21 +1712,38 @@ def tixcraft_auto_ocr(driver, ocr, ocr_captcha_with_submit): print("ddddocr is None") if not orc_answer is None: + orc_answer = orc_answer.strip() print("orc_answer:", orc_answer) if len(orc_answer)==4: - tixcraft_manully_keyin_verify_code(driver, answer = orc_answer) + who_care_var, is_form_sumbited = tixcraft_keyin_captcha_code(driver, answer = orc_answer, auto_submit = ocr_captcha_with_submit) else: - tixcraft_manully_keyin_verify_code(driver) - tixcraft_toast(driver, "※ Ocr fail...") + if not ocr_captcha_force_submit: + tixcraft_keyin_captcha_code(driver) + tixcraft_toast(driver, "※ Ocr fail...") + else: + is_need_redo_ocr = True + if previous_answer != orc_answer: + previous_answer = orc_answer + print("click captcha again") + tixcraft_reload_captcha(driver) + time.sleep(0.3) else: - tixcraft_manully_keyin_verify_code(driver) + print("orc_answer is None") + print("previous_answer:", previous_answer) + if previous_answer is None: + tixcraft_keyin_captcha_code(driver) + else: + # page is not ready, retry again. + is_need_redo_ocr = True + + return is_need_redo_ocr, previous_answer, is_form_sumbited def tixcraft_ticket_main(driver, config_dict, ocr): - is_finish_checkbox_click = False auto_check_agree = config_dict["auto_check_agree"] ocr_captcha_enable = config_dict["ocr_captcha"]["enable"] ocr_captcha_with_submit = config_dict["ocr_captcha"]["auto_submit"] + ocr_captcha_force_submit = config_dict["ocr_captcha"]["force_submit"] if auto_check_agree: tixcraft_ticket_agree(driver) @@ -1755,12 +1799,20 @@ def tixcraft_ticket_main(driver, config_dict, ocr): # must wait ticket number assign to focus captcha. if is_ticket_number_assigned: if not ocr_captcha_enable: - is_verifyCode_editing = tixcraft_manully_keyin_verify_code(driver) + is_verifyCode_editing = tixcraft_keyin_captcha_code(driver) else: - tixcraft_auto_ocr(driver, ocr, ocr_captcha_with_submit) + previous_answer = None is_verifyCode_editing = True - - print("is_finish_checkbox_click:", is_finish_checkbox_click) + for redo_ocr in range(999): + is_need_redo_ocr, previous_answer, is_form_sumbited = tixcraft_auto_ocr(driver, ocr, ocr_captcha_with_submit, ocr_captcha_force_submit, previous_answer) + if is_form_sumbited: + # start next loop. + is_verifyCode_editing = False + break + if not ocr_captcha_force_submit: + break + if not is_need_redo_ocr: + break if is_verifyCode_editing: print("goto is_verifyCode_editing == True") @@ -5154,7 +5206,7 @@ def main(): ocr = None try: if config_dict["ocr_captcha"]["enable"]: - ocr = ddddocr.DdddOcr() + ocr = ddddocr.DdddOcr(show_ad=False, beta=True) except Exception as exc: pass @@ -5332,8 +5384,8 @@ if __name__ == "__main__": print("inferred_answer_string:", inferred_answer_string) print("answer_list:", answer_list) - ocr = ddddocr.DdddOcr() - with open('captcha-oapi.png', 'rb') as f: + ocr = ddddocr.DdddOcr(show_ad=False, beta=True) + with open('captcha-xxxx.png', 'rb') as f: image_bytes = f.read() res = ocr.classification(image_bytes) print(res) diff --git a/settings.json b/settings.json index e8347a7..04b1591 100644 --- a/settings.json +++ b/settings.json @@ -1 +1 @@ -{"homepage": "https://tixcraft.com", "browser": "chrome", "language": "\u7e41\u9ad4\u4e2d\u6587", "ticket_number": 2, "pass_1_seat_remaining": true, "auto_check_agree": true, "ocr_captcha": {"enable": true, "auto_submit": false}, "kktix": {"auto_press_next_step_button": true, "auto_fill_ticket_number": true, "area_mode": "from top to bottom", "area_keyword_1": "", "area_keyword_1_and": "", "area_keyword_2": "", "area_keyword_2_and": "", "auto_guess_options": false, "user_guess_string": ""}, "tixcraft": {"date_auto_select": {"enable": true, "date_keyword": "", "mode": "from top to bottom"}, "area_auto_select": {"enable": true, "area_keyword_1": "", "area_keyword_2": "", "area_keyword_3": "", "area_keyword_4": "", "mode": "from top to bottom"}, "pass_date_is_sold_out": true, "auto_reload_coming_soon_page": true, "presale_code": ""}, "advanced": {"play_captcha_sound": {"enable": true, "filename": "ding-dong.wav"}, "facebook_account": "", "kktix_account": "", "adblock_plus_enable": true}, "debug": false} \ No newline at end of file +{"homepage": "https://tixcraft.com", "browser": "chrome", "language": "\u7e41\u9ad4\u4e2d\u6587", "ticket_number": 2, "pass_1_seat_remaining": true, "auto_check_agree": true, "ocr_captcha": {"enable": true, "auto_submit": true, "force_submit": true}, "kktix": {"auto_press_next_step_button": true, "auto_fill_ticket_number": true, "area_mode": "from top to bottom", "area_keyword_1": "", "area_keyword_1_and": "", "area_keyword_2": "", "area_keyword_2_and": "", "auto_guess_options": false, "user_guess_string": ""}, "tixcraft": {"date_auto_select": {"enable": true, "date_keyword": "", "mode": "from top to bottom"}, "area_auto_select": {"enable": true, "area_keyword_1": "", "area_keyword_2": "", "area_keyword_3": "", "area_keyword_4": "", "mode": "from top to bottom"}, "pass_date_is_sold_out": true, "auto_reload_coming_soon_page": true, "presale_code": ""}, "advanced": {"play_captcha_sound": {"enable": true, "filename": "ding-dong.wav"}, "facebook_account": "", "kktix_account": "", "adblock_plus_enable": false}, "debug": false} \ No newline at end of file diff --git a/settings.py b/settings.py index 5d22e55..d80f677 100644 --- a/settings.py +++ b/settings.py @@ -19,7 +19,7 @@ import json import webbrowser import pyperclip -CONST_APP_VERSION = u"MaxBot (2023.01.12)3版" +CONST_APP_VERSION = u"MaxBot (2023.01.13)" CONST_FROM_TOP_TO_BOTTOM = u"from top to bottom" CONST_FROM_BOTTOM_TO_TOP = u"from bottom to top" @@ -78,6 +78,7 @@ def load_translate(): en_us["pass_1_seat_remaining"] = 'Pass 1 seat remaining' en_us["ocr_captcha"] = 'OCR captcha' en_us["ocr_captcha_with_submit"] = 'After guess auto submit' + en_us["ocr_captcha_force_submit"] = 'Allow submit wrong answer' en_us["preference"] = 'Preference' en_us["advanced"] = 'Advanced' @@ -135,6 +136,7 @@ def load_translate(): zh_tw["pass_1_seat_remaining"] = '避開「剩餘 1」的區域' zh_tw["ocr_captcha"] = '猜測驗證碼' zh_tw["ocr_captcha_with_submit"] = '猜測後自動送出' + zh_tw["ocr_captcha_force_submit"] = '允許送出錯的驗證碼' zh_tw["preference"] = '偏好設定' zh_tw["advanced"] = '進階設定' @@ -192,6 +194,7 @@ def load_translate(): zh_cn["pass_1_seat_remaining"] = '避开“剩余 1”的区域' zh_cn["ocr_captcha"] = '猜测验证码' zh_cn["ocr_captcha_with_submit"] = '猜测后自动送出' + zh_cn["ocr_captcha_force_submit"] = '允许送出错的验证码' zh_cn["preference"] = '偏好设定' zh_cn["advanced"] = '進階設定' @@ -250,6 +253,7 @@ def load_translate(): ja_jp["pass_1_seat_remaining"] = '「1 席残り」エリアは避ける' ja_jp["ocr_captcha"] = 'キャプチャを推測する' ja_jp["ocr_captcha_with_submit"] = '提出で推測した後' + zh_cn["ocr_captcha_force_submit"] = '間違った回答の送信を許可する' ja_jp["preference"] = '設定' ja_jp["advanced"] = '高度な設定' @@ -303,6 +307,7 @@ def get_default_config(): config_dict["ocr_captcha"] = {} config_dict["ocr_captcha"]["enable"] = True config_dict["ocr_captcha"]["auto_submit"] = False + config_dict["ocr_captcha"]["force_submit"] = False config_dict['kktix']={} config_dict["kktix"]["auto_press_next_step_button"] = True @@ -425,6 +430,7 @@ def btn_save_act(language_code, slience_mode=False): global chk_state_adblock_plus global chk_state_ocr_captcha global chk_state_ocr_captcha_with_submit + global chk_state_ocr_captcha_force_submit is_all_data_correct = True @@ -500,6 +506,7 @@ def btn_save_act(language_code, slience_mode=False): config_dict["ocr_captcha"] = {} config_dict["ocr_captcha"]["enable"] = bool(chk_state_ocr_captcha.get()) config_dict["ocr_captcha"]["auto_submit"] = bool(chk_state_ocr_captcha_with_submit.get()) + config_dict["ocr_captcha"]["force_submit"] = bool(chk_state_ocr_captcha_force_submit.get()) # save config. if is_all_data_correct: @@ -661,6 +668,7 @@ def applyNewLanguage(): global lbl_presale_code global lbl_ocr_captcha global lbl_ocr_captcha_with_submit + global lbl_ocr_captcha_force_submit # for checkbox global chk_pass_1_seat_remaining @@ -677,6 +685,7 @@ def applyNewLanguage(): global chk_adblock_plus global chk_ocr_captcha global chk_ocr_captcha_with_sumit + global chk_ocr_captcha_force_sumit global tabControl @@ -720,6 +729,7 @@ def applyNewLanguage(): lbl_presale_code.config(text=translate[language_code]["user_guess_string"]) lbl_ocr_captcha.config(text=translate[language_code]["ocr_captcha"]) lbl_ocr_captcha_with_submit.config(text=translate[language_code]["ocr_captcha_with_submit"]) + lbl_ocr_captcha_force_submit.config(text=translate[language_code]["ocr_captcha_force_submit"]) chk_pass_1_seat_remaining.config(text=translate[language_code]["enable"]) chk_auto_check_agree.config(text=translate[language_code]["enable"]) @@ -734,6 +744,7 @@ def applyNewLanguage(): chk_adblock_plus.config(text=translate[language_code]["enable"]) chk_ocr_captcha.config(text=translate[language_code]["enable"]) chk_ocr_captcha_with_sumit.config(text=translate[language_code]["enable"]) + chk_ocr_captcha_force_sumit.config(text=translate[language_code]["enable"]) tabControl.tab(0, text=translate[language_code]["preference"]) tabControl.tab(1, text=translate[language_code]["advanced"]) @@ -825,6 +836,22 @@ def showHideOcrCaptchaWithSubmit(): lbl_ocr_captcha_with_submit.grid_forget() chk_ocr_captcha_with_sumit.grid_forget() + global chk_state_ocr_captcha_with_submit + is_ocr_captcha_auto_submit_enable = bool(chk_state_ocr_captcha_with_submit.get()) + + global ocr_captcha_force_submit_index + global lbl_ocr_captcha_force_submit + global chk_ocr_captcha_force_sumit + + if is_ocr_captcha_auto_submit_enable: + # show. + lbl_ocr_captcha_force_submit.grid(column=0, row=ocr_captcha_force_submit_index, sticky = E) + chk_ocr_captcha_force_sumit.grid(column=1, row=ocr_captcha_force_submit_index, sticky = W) + else: + # hide + lbl_ocr_captcha_force_submit.grid_forget() + chk_ocr_captcha_force_sumit.grid_forget() + def showHidePass1SeatRemaining(): global combo_ticket_number ticket_number_int = int(combo_ticket_number.get().strip()) @@ -1501,9 +1528,27 @@ def PreferenctTab(root, config_dict, language_code, UI_PADDING_X): chk_state_ocr_captcha_with_submit.set(config_dict['ocr_captcha']["auto_submit"]) global chk_ocr_captcha_with_sumit - chk_ocr_captcha_with_sumit = Checkbutton(frame_group_tixcraft, text=translate[language_code]['enable'], variable=chk_state_ocr_captcha_with_submit) + chk_ocr_captcha_with_sumit = Checkbutton(frame_group_tixcraft, text=translate[language_code]['enable'], variable=chk_state_ocr_captcha_with_submit, command=showHideOcrCaptchaWithSubmit) chk_ocr_captcha_with_sumit.grid(column=1, row=group_row_count, sticky = W) + group_row_count+=1 + + global ocr_captcha_force_submit_index + ocr_captcha_force_submit_index = group_row_count + + global lbl_ocr_captcha_force_submit + lbl_ocr_captcha_force_submit = Label(frame_group_tixcraft, text=translate[language_code]['ocr_captcha_force_submit']) + lbl_ocr_captcha_force_submit.grid(column=0, row=ocr_captcha_force_submit_index, sticky = E) + + global chk_state_ocr_captcha_force_submit + chk_state_ocr_captcha_force_submit = BooleanVar() + chk_state_ocr_captcha_force_submit.set(config_dict['ocr_captcha']["force_submit"]) + + global chk_ocr_captcha_force_sumit + chk_ocr_captcha_force_sumit = Checkbutton(frame_group_tixcraft, text=translate[language_code]['enable'], variable=chk_state_ocr_captcha_force_submit) + chk_ocr_captcha_force_sumit.grid(column=1, row=group_row_count, sticky = W) + + # final flush. global frame_group_tixcraft_index frame_group_tixcraft_index = row_count #PS: don't need show when onload(), because show/hide block will load again. @@ -1816,7 +1861,7 @@ def main(): load_GUI(root, config_dict) GUI_SIZE_WIDTH = 460 - GUI_SIZE_HEIGHT = 594 + GUI_SIZE_HEIGHT = 615 GUI_SIZE_MACOS = str(GUI_SIZE_WIDTH) + 'x' + str(GUI_SIZE_HEIGHT) GUI_SIZE_WINDOWS=str(GUI_SIZE_WIDTH-60) + 'x' + str(GUI_SIZE_HEIGHT-90)