2022-11-19, fix KKTix auto press next button bug.

master
CHUN YU YAO 2022-11-19 06:59:34 +08:00
parent 805bd8c1c9
commit 6289db1993
2 changed files with 684 additions and 642 deletions

View File

@ -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》演唱會是以下哪位藝人的演出請以半形輸入法作答大小寫需要一模一樣範例B2A1.周杰倫 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:

View File

@ -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