2022-11-19, fix KKTix auto press next button bug.
parent
805bd8c1c9
commit
6289db1993
|
@ -39,7 +39,7 @@ warnings.simplefilter('ignore',InsecureRequestWarning)
|
|||
import ssl
|
||||
ssl._create_default_https_context = ssl._create_unverified_context
|
||||
|
||||
CONST_APP_VERSION = u"MaxBot (2022.11.18)"
|
||||
CONST_APP_VERSION = u"MaxBot (2022.11.19)"
|
||||
|
||||
CONST_FROM_TOP_TO_BOTTOM = u"from top to bottom"
|
||||
CONST_FROM_BOTTOM_TO_TOP = u"from bottom to top"
|
||||
|
@ -52,8 +52,6 @@ CONT_STRING_1_SEATS_REMAINING = [u'@1 seat(s) remaining',u'剩餘 1@',u'@1 席
|
|||
|
||||
driver = None
|
||||
|
||||
homepage = None
|
||||
browser = None
|
||||
ticket_number = None
|
||||
|
||||
auto_press_next_step_button = False
|
||||
|
@ -81,13 +79,6 @@ kktix_area_auto_select_mode = None
|
|||
kktix_area_keyword = None
|
||||
kktix_date_keyword = None
|
||||
|
||||
kktix_answer_dictionary = None
|
||||
kktix_answer_dictionary_list = None
|
||||
|
||||
auto_guess_options = False
|
||||
|
||||
debugMode = False
|
||||
|
||||
def get_app_root():
|
||||
# 讀取檔案裡的參數值
|
||||
basis = ""
|
||||
|
@ -276,38 +267,37 @@ def close_browser_tabs(driver):
|
|||
def get_driver_by_config(config_dict, driver_type):
|
||||
global driver
|
||||
|
||||
global homepage
|
||||
global browser
|
||||
global debugMode
|
||||
global ticket_number
|
||||
global auto_press_next_step_button
|
||||
global auto_fill_ticket_number
|
||||
global kktix_area_auto_select_mode
|
||||
global kktix_area_keyword
|
||||
global kktix_date_keyword
|
||||
homepage = None
|
||||
browser = None
|
||||
language = "English"
|
||||
ticket_number = "2"
|
||||
|
||||
global kktix_answer_dictionary
|
||||
global kktix_answer_dictionary_list
|
||||
auto_press_next_step_button = False # default not checked.
|
||||
auto_fill_ticket_number = False # default not checked.
|
||||
auto_guess_options = False # default not checked.
|
||||
|
||||
global auto_guess_options
|
||||
global pass_1_seat_remaining_enable
|
||||
global pass_date_is_sold_out_enable
|
||||
global auto_reload_coming_soon_page_enable
|
||||
kktix_area_auto_select_mode = ""
|
||||
kktix_area_keyword = ""
|
||||
kktix_date_keyword = ""
|
||||
|
||||
global area_keyword_1
|
||||
global area_keyword_2
|
||||
global area_keyword_3
|
||||
global area_keyword_4
|
||||
pass_1_seat_remaining_enable = False # default not checked.
|
||||
pass_date_is_sold_out_enable = False # default not checked.
|
||||
auto_reload_coming_soon_page_enable = True # default checked.
|
||||
|
||||
global date_auto_select_enable
|
||||
global date_auto_select_mode
|
||||
area_keyword_1 = ""
|
||||
area_keyword_2 = ""
|
||||
area_keyword_3 = ""
|
||||
area_keyword_4 = ""
|
||||
|
||||
global date_keyword
|
||||
date_keyword = ""
|
||||
|
||||
global area_auto_select_enable
|
||||
global area_auto_select_mode
|
||||
date_auto_select_enable = None
|
||||
date_auto_select_mode = ""
|
||||
|
||||
global debugMode
|
||||
area_auto_select_enable = None
|
||||
area_auto_select_mode = ""
|
||||
|
||||
debugMode = False
|
||||
|
||||
if not config_dict is None:
|
||||
# read config.
|
||||
|
@ -350,14 +340,7 @@ def get_driver_by_config(config_dict, driver_type):
|
|||
kktix_date_keyword = kktix_date_keyword.strip()
|
||||
|
||||
# disable password brute force attack
|
||||
if 'answer_dictionary' in config_dict["kktix"]:
|
||||
kktix_answer_dictionary = config_dict["kktix"]["answer_dictionary"]
|
||||
if kktix_answer_dictionary is None:
|
||||
kktix_answer_dictionary = ""
|
||||
kktix_answer_dictionary = kktix_answer_dictionary.strip()
|
||||
|
||||
if len(kktix_answer_dictionary) > 0:
|
||||
kktix_answer_dictionary_list = kktix_answer_dictionary.split(',')
|
||||
# PS: because of the question is always variable.
|
||||
|
||||
if 'auto_guess_options' in config_dict["kktix"]:
|
||||
auto_guess_options = config_dict["kktix"]["auto_guess_options"]
|
||||
|
@ -429,7 +412,6 @@ def get_driver_by_config(config_dict, driver_type):
|
|||
print("auto_fill_ticket_number", auto_fill_ticket_number)
|
||||
print("kktix_area_keyword", kktix_area_keyword)
|
||||
print("kktix_date_keyword", kktix_date_keyword)
|
||||
print("kktix_answer_dictionary", kktix_answer_dictionary)
|
||||
print("auto_guess_options", auto_guess_options)
|
||||
|
||||
# for tixcraft
|
||||
|
@ -861,8 +843,6 @@ def get_answer_list_by_question(captcha_text_div_text):
|
|||
my_answer_delimitor = maybe_delimitor
|
||||
#print(u"my_answer_delimitor:", my_answer_delimitor)
|
||||
|
||||
|
||||
|
||||
# try all possible options.
|
||||
tmp_text = captcha_text_div_text
|
||||
tmp_text = tmp_text.replace(u' ',u' ')
|
||||
|
@ -1000,7 +980,7 @@ def tixcraft_redirect(driver, url):
|
|||
def tixcraft_date_auto_select(driver, url, config_dict):
|
||||
# read config.
|
||||
date_auto_select_mode = config_dict["tixcraft"]["date_auto_select"]["mode"]
|
||||
date_keyword = config_dict["tixcraft"]["date_auto_select"]["date_keyword"]
|
||||
date_keyword = config_dict["tixcraft"]["date_auto_select"]["date_keyword"].strip()
|
||||
pass_date_is_sold_out_enable = config_dict["tixcraft"]["pass_date_is_sold_out"]
|
||||
auto_reload_coming_soon_page_enable = config_dict["tixcraft"]["auto_reload_coming_soon_page"]
|
||||
|
||||
|
@ -1155,11 +1135,8 @@ def tixcraft_date_auto_select(driver, url, config_dict):
|
|||
# areas
|
||||
# PS: areas will be None, if length equals zero.
|
||||
def get_tixcraft_target_area(el, area_keyword, area_auto_select_mode, pass_1_seat_remaining_enable):
|
||||
debugMode = True
|
||||
debugMode = False # for online
|
||||
|
||||
if debugMode:
|
||||
print("testing keyword:", area_keyword)
|
||||
show_debug_message = True # debug.
|
||||
show_debug_message = False # online
|
||||
|
||||
is_need_refresh = False
|
||||
areas = None
|
||||
|
@ -1223,7 +1200,7 @@ def get_tixcraft_target_area(el, area_keyword, area_auto_select_mode, pass_1_sea
|
|||
is_append_this_row = True
|
||||
|
||||
if is_append_this_row:
|
||||
if debugMode:
|
||||
if show_debug_message:
|
||||
print("pass_1_seat_remaining_enable:", pass_1_seat_remaining_enable)
|
||||
if pass_1_seat_remaining_enable:
|
||||
area_item_font_el = None
|
||||
|
@ -1235,12 +1212,12 @@ def get_tixcraft_target_area(el, area_keyword, area_auto_select_mode, pass_1_sea
|
|||
if font_el_text is None:
|
||||
font_el_text = ""
|
||||
font_el_text = "@%s@" % (font_el_text)
|
||||
if debugMode:
|
||||
if show_debug_message:
|
||||
print('font tag text:', font_el_text)
|
||||
pass
|
||||
for check_item in CONT_STRING_1_SEATS_REMAINING:
|
||||
if check_item in font_el_text:
|
||||
if debugMode:
|
||||
if show_debug_message:
|
||||
print("match pass 1 seats remaining 1 full text:", row_text)
|
||||
print("match pass 1 seats remaining 2 font text:", font_el_text)
|
||||
is_append_this_row = False
|
||||
|
@ -1251,7 +1228,7 @@ def get_tixcraft_target_area(el, area_keyword, area_auto_select_mode, pass_1_sea
|
|||
#print("find font text in a tag fail:", exc)
|
||||
pass
|
||||
|
||||
if debugMode:
|
||||
if show_debug_message:
|
||||
print("is_append_this_row:", is_append_this_row)
|
||||
|
||||
if is_append_this_row:
|
||||
|
@ -1260,7 +1237,7 @@ def get_tixcraft_target_area(el, area_keyword, area_auto_select_mode, pass_1_sea
|
|||
if area_auto_select_mode == CONST_FROM_TOP_TO_BOTTOM:
|
||||
print("only need first item, break area list loop.")
|
||||
break
|
||||
if debugMode:
|
||||
if show_debug_message:
|
||||
print("row_text:" + row_text)
|
||||
print("match:" + area_keyword)
|
||||
|
||||
|
@ -1281,10 +1258,10 @@ def tixcraft_area_auto_select(driver, url, config_dict):
|
|||
area_auto_select_mode = config_dict["tixcraft"]["area_auto_select"]["mode"]
|
||||
pass_1_seat_remaining_enable = config_dict["tixcraft"]["pass_1_seat_remaining"]
|
||||
|
||||
debugMode = True
|
||||
debugMode = False # for online
|
||||
show_debug_message = True # debug.
|
||||
show_debug_message = False # online
|
||||
|
||||
if debugMode:
|
||||
if show_debug_message:
|
||||
print("area_keyword_1, area_keyword_2:", area_keyword_1, area_keyword_2)
|
||||
print("area_keyword_3, area_keyword_4:", area_keyword_3, area_keyword_4)
|
||||
|
||||
|
@ -1299,40 +1276,40 @@ def tixcraft_area_auto_select(driver, url, config_dict):
|
|||
|
||||
if el is not None:
|
||||
is_need_refresh, areas = get_tixcraft_target_area(el, area_keyword_1, area_auto_select_mode, pass_1_seat_remaining_enable)
|
||||
if debugMode:
|
||||
if show_debug_message:
|
||||
print("is_need_refresh for keyword1:", is_need_refresh)
|
||||
|
||||
if is_need_refresh:
|
||||
if areas is None:
|
||||
if debugMode:
|
||||
if show_debug_message:
|
||||
print("use area keyword #2", area_keyword_2)
|
||||
|
||||
# only when keyword#2 filled to query.
|
||||
if len(area_keyword_2) > 0 :
|
||||
is_need_refresh, areas = get_tixcraft_target_area(el, area_keyword_2, area_auto_select_mode, pass_1_seat_remaining_enable)
|
||||
if debugMode:
|
||||
if show_debug_message:
|
||||
print("is_need_refresh for keyword2:", is_need_refresh)
|
||||
|
||||
if is_need_refresh:
|
||||
if areas is None:
|
||||
if debugMode:
|
||||
if show_debug_message:
|
||||
print("use area keyword #3", area_keyword_3)
|
||||
|
||||
# only when keyword#3 filled to query.
|
||||
if len(area_keyword_3) > 0 :
|
||||
is_need_refresh, areas = get_tixcraft_target_area(el, area_keyword_3, area_auto_select_mode, pass_1_seat_remaining_enable)
|
||||
if debugMode:
|
||||
if show_debug_message:
|
||||
print("is_need_refresh for keyword3:", is_need_refresh)
|
||||
|
||||
if is_need_refresh:
|
||||
if areas is None:
|
||||
if debugMode:
|
||||
if show_debug_message:
|
||||
print("use area keyword #4", area_keyword_4)
|
||||
|
||||
# only when keyword#4 filled to query.
|
||||
if len(area_keyword_4) > 0 :
|
||||
is_need_refresh, areas = get_tixcraft_target_area(el, area_keyword_4, area_auto_select_mode, pass_1_seat_remaining_enable)
|
||||
if debugMode:
|
||||
if show_debug_message:
|
||||
print("is_need_refresh for keyword4:", is_need_refresh)
|
||||
|
||||
area_target = None
|
||||
|
@ -1838,16 +1815,25 @@ def kktix_input_captcha_text(captcha_inner_div, captcha_password_string, force_o
|
|||
|
||||
ret = False
|
||||
|
||||
if captcha_inner_div is not None and captcha_password_string is not None:
|
||||
captcha_password_text = None
|
||||
try:
|
||||
if show_debug_message:
|
||||
print("found captcha div")
|
||||
captcha_password_text = captcha_inner_div.find_element(By.TAG_NAME, "input")
|
||||
if not captcha_password_text is None:
|
||||
if show_debug_message:
|
||||
print("found input field")
|
||||
except Exception as exc:
|
||||
pass
|
||||
|
||||
if not captcha_password_text is None:
|
||||
inputed_captcha_text = ""
|
||||
try:
|
||||
inputed_captcha_text = captcha_password_text.get_attribute('value')
|
||||
except Exception as exc:
|
||||
pass
|
||||
if inputed_captcha_text is None:
|
||||
inputed_captcha_text = ""
|
||||
|
||||
if captcha_password_string is not None:
|
||||
try:
|
||||
if force_overwrite:
|
||||
captcha_password_text.send_keys(captcha_password_string)
|
||||
print("send captcha keys:" + captcha_password_string)
|
||||
|
@ -1860,9 +1846,19 @@ def kktix_input_captcha_text(captcha_inner_div, captcha_password_string, force_o
|
|||
ret = True
|
||||
except Exception as exc:
|
||||
if show_debug_message:
|
||||
print("find kktix_input_captcha_text Exception:")
|
||||
print("kktix_input_captcha_text Exception:")
|
||||
print(exc)
|
||||
pass
|
||||
else:
|
||||
# do focus()
|
||||
if len(inputed_captcha_text) == 0:
|
||||
try:
|
||||
print("focus() captcha to input.")
|
||||
captcha_password_text.click()
|
||||
time.sleep(1)
|
||||
# let user to input answer, bot sleep 1 second.
|
||||
except Exception as exc:
|
||||
pass
|
||||
|
||||
return ret
|
||||
|
||||
|
@ -1891,7 +1887,6 @@ def kktix_travel_price_list(driver, kktix_area_keyword, kktix_date_keyword):
|
|||
else:
|
||||
print("find ticket-price span fail")
|
||||
|
||||
|
||||
is_travel_interrupted = False
|
||||
|
||||
if price_list_count > 0:
|
||||
|
@ -2134,26 +2129,44 @@ def kktix_check_agree_checkbox(driver):
|
|||
person_agree_terms_checkbox = None
|
||||
try:
|
||||
person_agree_terms_checkbox = driver.find_element(By.ID, 'person_agree_terms')
|
||||
if person_agree_terms_checkbox is not None:
|
||||
if person_agree_terms_checkbox.is_enabled():
|
||||
#print("find person_agree_terms checkbox")
|
||||
if not person_agree_terms_checkbox.is_selected():
|
||||
#print('send check to checkbox')
|
||||
person_agree_terms_checkbox.click()
|
||||
is_finish_checkbox_click = True
|
||||
else:
|
||||
#print('checked')
|
||||
is_finish_checkbox_click = True
|
||||
pass
|
||||
else:
|
||||
is_need_refresh = True
|
||||
else:
|
||||
is_need_refresh = True
|
||||
print("find person_agree_terms checkbox fail")
|
||||
except Exception as exc:
|
||||
print("find person_agree_terms checkbox Exception")
|
||||
pass
|
||||
|
||||
if person_agree_terms_checkbox is not None:
|
||||
is_visible = False
|
||||
try:
|
||||
if person_agree_terms_checkbox.is_enabled():
|
||||
is_visible = True
|
||||
except Exception as exc:
|
||||
pass
|
||||
|
||||
if is_visible:
|
||||
is_checkbox_checked = False
|
||||
try:
|
||||
if person_agree_terms_checkbox.is_selected():
|
||||
is_checkbox_checked = True
|
||||
except Exception as exc:
|
||||
pass
|
||||
|
||||
if not is_checkbox_checked:
|
||||
#print('send check to checkbox')
|
||||
try:
|
||||
person_agree_terms_checkbox.click()
|
||||
is_finish_checkbox_click = True
|
||||
except Exception as exc:
|
||||
pass
|
||||
else:
|
||||
#print('checked')
|
||||
is_finish_checkbox_click = True
|
||||
else:
|
||||
is_need_refresh = True
|
||||
else:
|
||||
is_need_refresh = True
|
||||
|
||||
if is_need_refresh:
|
||||
print("find person_agree_terms checkbox fail, do refresh page.")
|
||||
|
||||
return is_need_refresh, is_finish_checkbox_click
|
||||
|
||||
def kktix_check_register_status(url):
|
||||
|
@ -2208,53 +2221,16 @@ def kktix_check_register_status(url):
|
|||
#print("registerStatus:", registerStatus)
|
||||
return registerStatus
|
||||
|
||||
def kktix_reg_new_main(url, answer_index, registrationsNewApp_div, is_finish_checkbox_click, config_dict):
|
||||
# read config.
|
||||
auto_press_next_step_button = config_dict["kktix"]["auto_press_next_step_button"]
|
||||
auto_fill_ticket_number = config_dict["kktix"]["auto_fill_ticket_number"]
|
||||
ticket_number = str(config_dict["ticket_number"])
|
||||
kktix_area_keyword = config_dict["kktix"]["area_keyword"].strip()
|
||||
kktix_date_keyword = config_dict["kktix"]["date_keyword"].strip()
|
||||
kktix_area_auto_select_mode = config_dict["kktix"]["area_mode"]
|
||||
auto_guess_options = config_dict["kktix"]["auto_guess_options"]
|
||||
|
||||
def kktix_reg_new_captcha(driver, captcha_inner_div, auto_guess_options):
|
||||
show_debug_message = True # debug.
|
||||
show_debug_message = False # online
|
||||
|
||||
#---------------------------
|
||||
# part 2: ticket number
|
||||
#---------------------------
|
||||
is_assign_ticket_number = False
|
||||
if auto_fill_ticket_number:
|
||||
for retry_index in range(8):
|
||||
is_assign_ticket_number = kktix_assign_ticket_number(driver, ticket_number, kktix_area_auto_select_mode, kktix_area_keyword, kktix_date_keyword)
|
||||
if is_assign_ticket_number:
|
||||
break
|
||||
#print('is_assign_ticket_number:', is_assign_ticket_number)
|
||||
|
||||
#---------------------------
|
||||
# part 3: captcha
|
||||
#---------------------------
|
||||
# is captcha div appear
|
||||
is_captcha_appear = False
|
||||
is_captcha_appear_and_filled_password = False
|
||||
|
||||
# try to auto answer options.
|
||||
answer_list = None
|
||||
is_need_keep_symbol = False
|
||||
my_answer_delimitor = ""
|
||||
|
||||
captcha_inner_div = None
|
||||
try:
|
||||
captcha_inner_div = driver.find_element(By.CSS_SELECTOR, '.custom-captcha-inner')
|
||||
except Exception as exc:
|
||||
#print(exc)
|
||||
#print("find captcha_inner_div fail")
|
||||
pass
|
||||
|
||||
if captcha_inner_div is not None:
|
||||
if show_debug_message:
|
||||
print("found captcha_inner_div layor.")
|
||||
captcha_password_string = None
|
||||
|
||||
captcha_text_div = None
|
||||
try:
|
||||
|
@ -2264,12 +2240,8 @@ def kktix_reg_new_main(url, answer_index, registrationsNewApp_div, is_finish_che
|
|||
print("find p tag(captcha_text_div) fail")
|
||||
print(exc)
|
||||
|
||||
captcha_password_string = None
|
||||
captcha_text_div_text = None
|
||||
|
||||
if captcha_text_div is not None:
|
||||
is_captcha_appear = True
|
||||
|
||||
try:
|
||||
captcha_text_div_text = captcha_text_div.text
|
||||
except Exception as exc:
|
||||
|
@ -2329,7 +2301,6 @@ def kktix_reg_new_main(url, answer_index, registrationsNewApp_div, is_finish_che
|
|||
captcha_password_string = find_between(captcha_text_div_text, u"【", u"】")
|
||||
#print("find captcha text:" , captcha_password_string)
|
||||
|
||||
|
||||
# 請回答下列問題,請在下方空格輸入DELIGHT(請以半形輸入法作答,大小寫需要一模一樣)
|
||||
if captcha_password_string is None:
|
||||
# clean stop word
|
||||
|
@ -2352,16 +2323,6 @@ def kktix_reg_new_main(url, answer_index, registrationsNewApp_div, is_finish_che
|
|||
captcha_password_string = captcha_password_string.replace(u'內',u'')
|
||||
captcha_password_string = captcha_password_string.replace(u'文字',u'')
|
||||
|
||||
#captcha_text_div_text = "請問下列哪張專輯為林俊傑出道專輯?(1A)飛行者(2B)礫行者(3C)樂行者(請以半形輸入法作答,大小寫需要一模一樣,範例:1A)"
|
||||
#captcha_text_div_text = "以下哪個「不是」正確的林俊傑與其他藝人合唱的歌曲組合?(選項為歌名/合作藝人 ,請以半形輸入法作答選項,大小寫需要一模一樣,範例:jju) 選項: (jjz)I am alive/Jason Mraz (jjy)友人說/張懷秋 (jjx)豆漿油條/A-Sa蔡卓妍 (jjw)黑暗騎士/五月天阿信 (jjv)手心的薔薇/G.E.M鄧紫棋"
|
||||
|
||||
# for test.
|
||||
#captcha_password_string = None
|
||||
#captcha_text_div_text = u"以下哪個「不是」正確的林俊傑與其他藝人合唱的歌曲組合?(選項為歌名/合作藝人 ,請以半形輸入法作答選項,大小寫需要一模一樣,範例:jju) 選項: (jja)小酒窩/A-Sa蔡卓妍 (jjb)被風吹過的夏天/金莎 (jjc)友人說/張懷秋 (jjd)全面開戰/五月天阿信 (jje)小說/阿杜, (0118eveconcert)0118eveconcert"
|
||||
#captcha_text_div_text = u"以下哪個「不是」正確的林俊傑與其他藝人合唱的歌曲組合?(選項為歌名/合作藝人 ,請以半形輸入法作答選項,大小寫需要一模一樣,範例:jju) 選項: (jja)小酒窩/A-Sa蔡卓妍 (jjb)被風吹過的夏天/金莎 (jjc)友人說/張懷秋 (jjd)全面開戰/五月天阿信 (jje)小說/阿杜"
|
||||
#captcha_text_div_text = u"以下哪個「不是」正確的林俊傑與其他藝人合唱的歌曲組合?(選項為歌名/合作藝人 ,請以半形輸入法作答選項,大小寫需要一模一樣,範例:jju) 選項: (jja)小酒窩/A-Sa蔡卓妍 (jjb)被風吹過的夏天/金莎 (jjc)友人說/張懷秋 (jjd)全面開戰/五月天阿信 (jje)小說/阿杜"
|
||||
#captcha_text_div_text = u"請問《龍的傳人2060》演唱會是以下哪位藝人的演出?(請以半形輸入法作答,大小寫需要一模一樣,範例:B2)A1.周杰倫 B2.林俊傑 C3.張學友 D4.王力宏 4:4"
|
||||
|
||||
# parse '演出日期'
|
||||
is_need_parse_web_datetime = False
|
||||
# '半形阿拉伯數字' & '半形數字'
|
||||
|
@ -2629,76 +2590,137 @@ def kktix_reg_new_main(url, answer_index, registrationsNewApp_div, is_finish_che
|
|||
# no need guess options.
|
||||
pass
|
||||
|
||||
return captcha_password_string, answer_list, my_answer_delimitor
|
||||
|
||||
def kktix_double_check_all_text_value(driver, ticket_number):
|
||||
is_do_press_next_button = False
|
||||
|
||||
# double check ticket input textbox.
|
||||
ticket_price_input_list = None
|
||||
try:
|
||||
# PS: unable directly access text's value attribute via css selector or xpath on KKTix!
|
||||
my_css_selector = "input[type='text']"
|
||||
#print("my_css_selector:", my_css_selector)
|
||||
ticket_price_input_list = driver.find_elements(By.CSS_SELECTOR, my_css_selector)
|
||||
except Exception as exc:
|
||||
pass
|
||||
|
||||
if ticket_price_input_list is not None:
|
||||
#print("bingo, found one of ticket number textbox.")
|
||||
row_index = 0
|
||||
for ticket_price_input in ticket_price_input_list:
|
||||
row_index += 1
|
||||
current_ticket_number = ""
|
||||
try:
|
||||
current_ticket_number = str(ticket_price_input.get_attribute('value')).strip()
|
||||
except Exception as exc:
|
||||
pass
|
||||
if current_ticket_number is None:
|
||||
current_ticket_number = ""
|
||||
if len(current_ticket_number) > 0:
|
||||
#print(row_index, "current_ticket_number:", current_ticket_number)
|
||||
if current_ticket_number == ticket_number:
|
||||
#print("bingo, match target ticket number.")
|
||||
|
||||
# ONLY, this case to auto press next button.
|
||||
is_do_press_next_button = True
|
||||
break
|
||||
|
||||
return is_do_press_next_button
|
||||
|
||||
def kktix_reg_new_main(driver, answer_index, is_finish_checkbox_click, config_dict):
|
||||
show_debug_message = True # debug.
|
||||
show_debug_message = False # online
|
||||
|
||||
# part 1: check div.
|
||||
registrationsNewApp_div = None
|
||||
try:
|
||||
registrationsNewApp_div = driver.find_element(By.CSS_SELECTOR, '#registrationsNewApp')
|
||||
except Exception as exc:
|
||||
pass
|
||||
#print("find input fail:", exc)
|
||||
|
||||
# part 2: assign ticket number
|
||||
ticket_number = str(config_dict["ticket_number"])
|
||||
is_assign_ticket_number = False
|
||||
if not registrationsNewApp_div is None:
|
||||
kktix_area_auto_select_mode = config_dict["kktix"]["area_mode"]
|
||||
kktix_area_keyword = config_dict["kktix"]["area_keyword"].strip()
|
||||
kktix_date_keyword = config_dict["kktix"]["date_keyword"].strip()
|
||||
|
||||
for retry_index in range(3):
|
||||
is_assign_ticket_number = kktix_assign_ticket_number(driver, ticket_number, kktix_area_auto_select_mode, kktix_area_keyword, kktix_date_keyword)
|
||||
if is_assign_ticket_number:
|
||||
break
|
||||
#print('is_assign_ticket_number:', is_assign_ticket_number)
|
||||
|
||||
# part 3: captcha
|
||||
is_captcha_appear = False
|
||||
is_captcha_appear_and_filled_password = False
|
||||
answer_list = None
|
||||
|
||||
if is_assign_ticket_number:
|
||||
# TODO: in guess options mode, no need to travel div again.
|
||||
captcha_inner_div = None
|
||||
try:
|
||||
captcha_inner_div = driver.find_element(By.CSS_SELECTOR, '.custom-captcha-inner')
|
||||
except Exception as exc:
|
||||
pass
|
||||
|
||||
captcha_password_string = None
|
||||
if captcha_inner_div is not None:
|
||||
is_captcha_appear = True
|
||||
if show_debug_message:
|
||||
print("found captcha_inner_div layor.")
|
||||
|
||||
auto_guess_options = config_dict["kktix"]["auto_guess_options"]
|
||||
captcha_password_string, answer_list, my_answer_delimitor = kktix_reg_new_captcha(driver, captcha_inner_div, auto_guess_options)
|
||||
|
||||
# final run.
|
||||
if captcha_password_string is not None:
|
||||
# password is not None, try to send.
|
||||
# password is None, focus to input.
|
||||
if kktix_input_captcha_text(captcha_inner_div, captcha_password_string):
|
||||
is_captcha_appear_and_filled_password = True
|
||||
|
||||
if auto_press_next_step_button:
|
||||
# pass switch check.
|
||||
if show_debug_message:
|
||||
print("is_captcha_appear:", is_captcha_appear)
|
||||
print("is_captcha_appear_and_filled_password:", is_captcha_appear_and_filled_password)
|
||||
|
||||
#print("is_assign_ticket_number", is_assign_ticket_number)
|
||||
if is_assign_ticket_number:
|
||||
# must input the ticket number correct.
|
||||
#print("is_captcha_appear:", is_captcha_appear)
|
||||
#print("is_captcha_appear_and_filled_password:", is_captcha_appear_and_filled_password)
|
||||
|
||||
# must ensure checkbox has been checked.
|
||||
# retry check agree checkbox again.
|
||||
if not is_finish_checkbox_click:
|
||||
for retry_i in range(5):
|
||||
# retry again.
|
||||
is_need_refresh, is_finish_checkbox_click = kktix_check_agree_checkbox(driver)
|
||||
time.sleep(0.1)
|
||||
if is_finish_checkbox_click:
|
||||
break
|
||||
|
||||
if not is_captcha_appear:
|
||||
# without captcha.
|
||||
# normal mode.
|
||||
#print("# normal mode.")
|
||||
is_do_press_next_button = False
|
||||
if is_assign_ticket_number:
|
||||
auto_press_next_step_button = config_dict["kktix"]["auto_press_next_step_button"]
|
||||
if auto_press_next_step_button:
|
||||
if is_finish_checkbox_click:
|
||||
click_ret = kktix_press_next_button(driver)
|
||||
if not click_ret:
|
||||
print("press next button fail, retry again.")
|
||||
click_ret = kktix_press_next_button(driver)
|
||||
is_do_press_next_button = kktix_double_check_all_text_value(driver, ticket_number)
|
||||
else:
|
||||
#print("press next button successfully.")
|
||||
pass
|
||||
else:
|
||||
print("unable to assign checkbox value")
|
||||
print("still unable to assign checkbox as selected.")
|
||||
|
||||
if show_debug_message:
|
||||
print("is_do_press_next_button:", is_do_press_next_button)
|
||||
|
||||
if is_do_press_next_button:
|
||||
if not is_captcha_appear:
|
||||
click_ret = kktix_press_next_button(driver)
|
||||
else:
|
||||
if is_captcha_appear_and_filled_password:
|
||||
# for easy guest mode, we can fill the password correct.
|
||||
#print("for easy guest mode, we can fill the password correct.")
|
||||
if is_finish_checkbox_click:
|
||||
click_ret = kktix_press_next_button(driver)
|
||||
if not click_ret:
|
||||
print("press next button fail, retry again.")
|
||||
click_ret = kktix_press_next_button(driver)
|
||||
else:
|
||||
#print("press next button successfully.")
|
||||
pass
|
||||
else:
|
||||
print("unable to assign checkbox value")
|
||||
else:
|
||||
# not is easy guest mode.
|
||||
#print("# not is easy guest mode.")
|
||||
|
||||
# password force brute
|
||||
if answer_list is None:
|
||||
if not kktix_answer_dictionary_list is None:
|
||||
if len(kktix_answer_dictionary_list) > 0:
|
||||
answer_list = kktix_answer_dictionary_list
|
||||
|
||||
# remove duplicate list
|
||||
# merge with password dictionary, so need remove duplicate list
|
||||
# PS: now, there are no password dictionary.
|
||||
if not answer_list is None:
|
||||
if len(answer_list) > 1:
|
||||
unique = [x for i, x in enumerate(answer_list) if answer_list.index(x) == i]
|
||||
answer_list = unique
|
||||
|
||||
# start to try
|
||||
# start to try answer.
|
||||
if not answer_list is None:
|
||||
# for popular event
|
||||
if len(answer_list) > 0:
|
||||
|
@ -2761,22 +2783,12 @@ def kktix_reg_new(driver, url, answer_index, kktix_register_status_last, config_
|
|||
|
||||
if not is_need_refresh:
|
||||
is_need_refresh, is_finish_checkbox_click = kktix_check_agree_checkbox(driver)
|
||||
|
||||
if not is_need_refresh:
|
||||
if not is_finish_checkbox_click:
|
||||
# retry again.
|
||||
is_need_refresh, is_finish_checkbox_click = kktix_check_agree_checkbox(driver)
|
||||
#print('check agree_terms_checkbox, is_need_refresh:',is_need_refresh)
|
||||
|
||||
# check is able to buy.
|
||||
registrationsNewApp_div = None
|
||||
el_list = None
|
||||
if not is_need_refresh:
|
||||
try:
|
||||
registrationsNewApp_div = driver.find_element(By.CSS_SELECTOR, '#registrationsNewApp')
|
||||
except Exception as exc:
|
||||
pass
|
||||
#print("find input fail:", exc)
|
||||
|
||||
if is_need_refresh:
|
||||
try:
|
||||
print("try to refresh page...")
|
||||
|
@ -2789,7 +2801,10 @@ def kktix_reg_new(driver, url, answer_index, kktix_register_status_last, config_
|
|||
answer_index = -1
|
||||
registerStatus = None
|
||||
else:
|
||||
answer_index = kktix_reg_new_main(url, answer_index, registrationsNewApp_div, is_finish_checkbox_click, config_dict)
|
||||
# check is able to buy.
|
||||
auto_fill_ticket_number = config_dict["kktix"]["auto_fill_ticket_number"]
|
||||
if auto_fill_ticket_number:
|
||||
answer_index = kktix_reg_new_main(driver, answer_index, is_finish_checkbox_click, config_dict)
|
||||
|
||||
return answer_index, registerStatus
|
||||
|
||||
|
@ -2994,17 +3009,18 @@ def fami_activity(driver):
|
|||
def fami_home(driver, url, config_dict):
|
||||
#print("fami_home bingo")
|
||||
|
||||
global is_assign_ticket_number
|
||||
global ticket_number
|
||||
is_assign_ticket_number = False
|
||||
|
||||
global date_keyword
|
||||
global area_keyword_1
|
||||
global area_keyword_2
|
||||
global area_keyword_3
|
||||
global area_keyword_4
|
||||
ticket_number = str(config_dict["ticket_number"])
|
||||
|
||||
global area_auto_select_mode
|
||||
date_keyword = config_dict["tixcraft"]["date_auto_select"]["date_keyword"].strip()
|
||||
|
||||
area_auto_select_mode = config_dict["tixcraft"]["area_auto_select"]["mode"]
|
||||
|
||||
area_keyword_1 = config_dict["tixcraft"]["area_auto_select"]["area_keyword_1"].strip()
|
||||
area_keyword_2 = config_dict["tixcraft"]["area_auto_select"]["area_keyword_2"].strip()
|
||||
area_keyword_3 = config_dict["tixcraft"]["area_auto_select"]["area_keyword_3"].strip()
|
||||
area_keyword_4 = config_dict["tixcraft"]["area_auto_select"]["area_keyword_4"].strip()
|
||||
|
||||
#---------------------------
|
||||
# part 3: fill ticket number.
|
||||
|
@ -3136,7 +3152,7 @@ def fami_home(driver, url, config_dict):
|
|||
except Exception as exc:
|
||||
pass
|
||||
|
||||
def urbtix_ticket_number_auto_select(driver, url, ticket_number):
|
||||
def urbtix_ticket_number_auto_select(driver, ticket_number):
|
||||
ret = False
|
||||
is_assign_ticket_number = False
|
||||
|
||||
|
@ -3187,7 +3203,7 @@ def urbtix_ticket_number_auto_select(driver, url, ticket_number):
|
|||
# True: area block appear.
|
||||
# False: area block not appear.
|
||||
# ps: return value for date auto select.
|
||||
def urbtix_area_auto_select(driver, url, kktix_area_keyword, kktix_date_keyword):
|
||||
def urbtix_area_auto_select(driver, kktix_area_keyword, kktix_date_keyword):
|
||||
ret = False
|
||||
areas = None
|
||||
|
||||
|
@ -3275,7 +3291,7 @@ def urbtix_area_auto_select(driver, url, kktix_area_keyword, kktix_date_keyword)
|
|||
|
||||
return ret
|
||||
|
||||
def urbtix_next_button_press(driver, url):
|
||||
def urbtix_next_button_press(driver):
|
||||
ret = False
|
||||
try:
|
||||
el = driver.find_element(By.CSS_SELECTOR, '#free-seat-purchase-btn')
|
||||
|
@ -3294,32 +3310,31 @@ def urbtix_next_button_press(driver, url):
|
|||
|
||||
return ret
|
||||
|
||||
def urbtix_performance(driver, url, config_dict):
|
||||
def urbtix_performance(driver, config_dict):
|
||||
#print("urbtix performance bingo")
|
||||
|
||||
global auto_fill_ticket_number
|
||||
global ticket_number
|
||||
|
||||
global kktix_area_keyword
|
||||
global kktix_date_keyword
|
||||
global auto_press_next_step_button
|
||||
kktix_area_keyword = config_dict["kktix"]["area_keyword"].strip()
|
||||
kktix_date_keyword = config_dict["kktix"]["date_keyword"].strip()
|
||||
|
||||
ticket_number = str(config_dict["ticket_number"])
|
||||
auto_fill_ticket_number = config_dict["kktix"]["auto_fill_ticket_number"]
|
||||
if auto_fill_ticket_number:
|
||||
area_div_exist = urbtix_area_auto_select(driver, url, kktix_area_keyword, kktix_date_keyword)
|
||||
area_div_exist = urbtix_area_auto_select(driver, kktix_area_keyword, kktix_date_keyword)
|
||||
|
||||
ticket_number_select_exist, is_assign_ticket_number = urbtix_ticket_number_auto_select(driver, url, ticket_number)
|
||||
ticket_number_select_exist, is_assign_ticket_number = urbtix_ticket_number_auto_select(driver, ticket_number)
|
||||
|
||||
# todo.
|
||||
auto_press_next_step_button = config_dict["kktix"]["auto_press_next_step_button"]
|
||||
if auto_press_next_step_button:
|
||||
if is_assign_ticket_number:
|
||||
urbtix_next_button_press(driver, url)
|
||||
urbtix_next_button_press(driver)
|
||||
|
||||
# purpose: area auto select
|
||||
# return:
|
||||
# True: area block appear.
|
||||
# False: area block not appear.
|
||||
# ps: return value for date auto select.
|
||||
def cityline_area_auto_select(url, kktix_area_keyword):
|
||||
def cityline_area_auto_select(driver, kktix_area_keyword):
|
||||
ret = False
|
||||
areas = None
|
||||
|
||||
|
@ -3421,7 +3436,7 @@ def cityline_area_auto_select(url, kktix_area_keyword):
|
|||
|
||||
return ret
|
||||
|
||||
def cityline_area_selected_text(url):
|
||||
def cityline_area_selected_text(driver):
|
||||
ret = None
|
||||
|
||||
area_list = None
|
||||
|
@ -3471,41 +3486,69 @@ def cityline_area_selected_text(url):
|
|||
return ret
|
||||
|
||||
|
||||
def cityline_ticket_number_auto_select(url):
|
||||
def cityline_ticket_number_auto_select(driver, ticket_number):
|
||||
ret = False
|
||||
is_assign_ticket_number = False
|
||||
selected_value = ""
|
||||
|
||||
el = None
|
||||
try:
|
||||
el = driver.find_element(By.CSS_SELECTOR, 'td.tix_type_select > div.chzn-container > a > span')
|
||||
except Exception as exc:
|
||||
#print("find ticket_number select fail")
|
||||
#print(exc)
|
||||
pass
|
||||
|
||||
is_visible = False
|
||||
if el is not None:
|
||||
try:
|
||||
if el.is_enabled():
|
||||
is_visible = True
|
||||
except Exception as exc:
|
||||
pass
|
||||
|
||||
selected_value = None
|
||||
if is_visible:
|
||||
ret = True
|
||||
selected_value = ""
|
||||
|
||||
try:
|
||||
selected_value = el.text
|
||||
#print("selected_value:", selected_value)
|
||||
|
||||
except Exception as exc:
|
||||
pass
|
||||
if selected_value is None:
|
||||
selected_value = ""
|
||||
|
||||
#print("selected_value:", selected_value)
|
||||
if selected_value == "0":
|
||||
try:
|
||||
el.click()
|
||||
time.sleep(0.3)
|
||||
except Exception as exc:
|
||||
pass
|
||||
|
||||
is_options_enabled = False
|
||||
|
||||
el_options = None
|
||||
try:
|
||||
el_options = driver.find_element(By.CSS_SELECTOR, 'td.tix_type_select > div.chzn-container > div.chzn-drop')
|
||||
if el_options is not None:
|
||||
if el_options.is_enabled():
|
||||
is_options_enabled = True
|
||||
|
||||
except Exception as exc:
|
||||
pass
|
||||
#print("is_options_enabled:", is_options_enabled)
|
||||
|
||||
el_options_li = None
|
||||
if is_options_enabled:
|
||||
try:
|
||||
el_options_li = driver.find_elements(By.CSS_SELECTOR, 'td.tix_type_select > div.chzn-container > div.chzn-drop > ul > li')
|
||||
except Exception as exc:
|
||||
pass
|
||||
if el_options_li is not None:
|
||||
if len(el_options_li) > 0:
|
||||
for row in el_options_li:
|
||||
if row is not None:
|
||||
try:
|
||||
if row.is_enabled():
|
||||
row_text = row.text
|
||||
if not row_text is None:
|
||||
|
@ -3515,14 +3558,12 @@ def cityline_ticket_number_auto_select(url):
|
|||
is_assign_ticket_number = True
|
||||
break
|
||||
except Exception as exc:
|
||||
#print("find ticket_number select fail")
|
||||
#print(exc)
|
||||
pass
|
||||
|
||||
return ret, is_assign_ticket_number
|
||||
|
||||
|
||||
def cityline_next_button_press(url):
|
||||
def cityline_next_button_press(driver):
|
||||
ret = False
|
||||
try:
|
||||
time.sleep(0.2)
|
||||
|
@ -3575,7 +3616,7 @@ def cityline_event(driver):
|
|||
|
||||
return ret
|
||||
|
||||
def cityline_captcha_auto_focus(url):
|
||||
def cityline_captcha_auto_focus(driver):
|
||||
ret = False
|
||||
try:
|
||||
el = driver.find_element(By.CSS_SELECTOR, 'input[name=verify]')
|
||||
|
@ -3616,32 +3657,33 @@ def cityline_captcha_auto_focus(url):
|
|||
|
||||
|
||||
def cityline_performance(driver, url, config_dict):
|
||||
#print("cityline bingo")
|
||||
is_assign_ticket_number = False
|
||||
|
||||
if "performance.do;" in url:
|
||||
cityline_captcha_auto_focus(url)
|
||||
cityline_captcha_auto_focus(driver)
|
||||
|
||||
global auto_fill_ticket_number
|
||||
global kktix_area_keyword
|
||||
global auto_press_next_step_button
|
||||
global is_assign_ticket_number
|
||||
kktix_area_keyword = config_dict["kktix"]["area_keyword"].strip()
|
||||
|
||||
auto_fill_ticket_number = config_dict["kktix"]["auto_fill_ticket_number"]
|
||||
if "?cid=" in url:
|
||||
if auto_fill_ticket_number:
|
||||
area_div_exist = False
|
||||
if len(kktix_area_keyword) > 0:
|
||||
area_div_exist = cityline_area_auto_select(url, kktix_area_keyword)
|
||||
area_div_exist = cityline_area_auto_select(driver, kktix_area_keyword)
|
||||
|
||||
ticket_number_select_exist, is_assign_ticket_number = cityline_ticket_number_auto_select(url)
|
||||
ticket_number = str(config_dict["ticket_number"])
|
||||
ticket_number_select_exist, is_assign_ticket_number = cityline_ticket_number_auto_select(driver, ticket_number)
|
||||
|
||||
# todo.
|
||||
auto_press_next_step_button = config_dict["kktix"]["auto_press_next_step_button"]
|
||||
if auto_press_next_step_button:
|
||||
if is_assign_ticket_number:
|
||||
selected_text = cityline_area_selected_text(url)
|
||||
selected_text = cityline_area_selected_text(driver)
|
||||
if not selected_text is None:
|
||||
if kktix_area_keyword in selected_text:
|
||||
# must same with our settting to auto press.
|
||||
for i in range(3):
|
||||
click_ret = cityline_next_button_press(url)
|
||||
click_ret = cityline_next_button_press(driver)
|
||||
if click_ret:
|
||||
break
|
||||
|
||||
|
@ -3793,7 +3835,7 @@ def main():
|
|||
answer_index = -1
|
||||
kktix_register_status_last = None
|
||||
|
||||
global debugMode
|
||||
debugMode = config_dict["debug"]
|
||||
if debugMode:
|
||||
print("Start to looping, detect browser url...")
|
||||
|
||||
|
@ -4023,7 +4065,7 @@ def main():
|
|||
pass
|
||||
|
||||
if '/performanceDetail/' in url:
|
||||
urbtix_performance(driver, url, config_dict)
|
||||
urbtix_performance(driver, config_dict)
|
||||
|
||||
if 'cityline.com' in url:
|
||||
if '/event.do' in url:
|
||||
|
|
|
@ -19,7 +19,7 @@ import json
|
|||
import webbrowser
|
||||
import pyperclip
|
||||
|
||||
CONST_APP_VERSION = u"MaxBot (2022.11.18)"
|
||||
CONST_APP_VERSION = u"MaxBot (2022.11.19)"
|
||||
|
||||
CONST_FROM_TOP_TO_BOTTOM = u"from top to bottom"
|
||||
CONST_FROM_BOTTOM_TO_TOP = u"from bottom to top"
|
||||
|
@ -797,6 +797,7 @@ def PreferenctTab(root, config_dict, language_code, UI_PADDING_X):
|
|||
kktix_area_keyword = ""
|
||||
kktix_date_keyword = ""
|
||||
# disable password brute force attack
|
||||
# PS: because of the question is always variable.
|
||||
#kktix_answer_dictionary = ""
|
||||
auto_guess_options = False # default not checked.
|
||||
|
||||
|
@ -875,8 +876,7 @@ def PreferenctTab(root, config_dict, language_code, UI_PADDING_X):
|
|||
date_auto_select_mode = CONST_SELECT_ORDER_DEFAULT
|
||||
|
||||
if 'date_keyword' in config_dict["tixcraft"]["date_auto_select"]:
|
||||
date_keyword = config_dict["tixcraft"]["date_auto_select"]["date_keyword"]
|
||||
date_keyword = date_keyword.strip()
|
||||
date_keyword = config_dict["tixcraft"]["date_auto_select"]["date_keyword"].strip()
|
||||
|
||||
area_auto_select_enable = False
|
||||
area_auto_select_mode = None
|
||||
|
|
Loading…
Reference in New Issue