2022-11-20, fix 2022-11-19's bug. fine tune tixcraft verify page. allow assign ticket count for cityline.
parent
708a11d642
commit
5db841acfe
|
@ -39,7 +39,7 @@ warnings.simplefilter('ignore',InsecureRequestWarning)
|
||||||
import ssl
|
import ssl
|
||||||
ssl._create_default_https_context = ssl._create_unverified_context
|
ssl._create_default_https_context = ssl._create_unverified_context
|
||||||
|
|
||||||
CONST_APP_VERSION = u"MaxBot (2022.11.19)"
|
CONST_APP_VERSION = u"MaxBot (2022.11.20)"
|
||||||
|
|
||||||
CONST_FROM_TOP_TO_BOTTOM = u"from top to bottom"
|
CONST_FROM_TOP_TO_BOTTOM = u"from top to bottom"
|
||||||
CONST_FROM_BOTTOM_TO_TOP = u"from bottom to top"
|
CONST_FROM_BOTTOM_TO_TOP = u"from bottom to top"
|
||||||
|
@ -160,7 +160,7 @@ def load_chromdriver_normal(webdriver_path, driver_type, adblock_plus_enable):
|
||||||
# for navigator.webdriver
|
# for navigator.webdriver
|
||||||
chrome_options.add_experimental_option("excludeSwitches", ['enable-automation'])
|
chrome_options.add_experimental_option("excludeSwitches", ['enable-automation'])
|
||||||
chrome_options.add_experimental_option('useAutomationExtension', False)
|
chrome_options.add_experimental_option('useAutomationExtension', False)
|
||||||
chrome_options.add_experimental_option("prefs", {"profile.password_manager_enabled": False, "credentials_enable_service": False,'profile.default_content_setting_values':{'notifications':2}})
|
chrome_options.add_experimental_option("prefs", {"credentials_enable_service": False, "profile.password_manager_enabled": False})
|
||||||
|
|
||||||
#caps = DesiredCapabilities().CHROME
|
#caps = DesiredCapabilities().CHROME
|
||||||
caps = chrome_options.to_capabilities()
|
caps = chrome_options.to_capabilities()
|
||||||
|
@ -170,13 +170,14 @@ def load_chromdriver_normal(webdriver_path, driver_type, adblock_plus_enable):
|
||||||
#caps["pageLoadStrategy"] = u"none"
|
#caps["pageLoadStrategy"] = u"none"
|
||||||
|
|
||||||
#caps["unhandledPromptBehavior"] = u"dismiss and notify" # default
|
#caps["unhandledPromptBehavior"] = u"dismiss and notify" # default
|
||||||
caps["unhandledPromptBehavior"] = u"ignore"
|
#caps["unhandledPromptBehavior"] = u"ignore"
|
||||||
#caps["unhandledPromptBehavior"] = u"dismiss"
|
#caps["unhandledPromptBehavior"] = u"dismiss"
|
||||||
|
caps["unhandledPromptBehavior"] = u"accept"
|
||||||
|
|
||||||
chrome_service = Service(chromedriver_path)
|
chrome_service = Service(chromedriver_path)
|
||||||
|
|
||||||
# method 6: Selenium Stealth
|
# method 6: Selenium Stealth
|
||||||
driver = webdriver.Chrome(service=chrome_service, options=chrome_options)
|
driver = webdriver.Chrome(service=chrome_service, options=chrome_options, desired_capabilities=caps)
|
||||||
|
|
||||||
if driver_type=="stealth":
|
if driver_type=="stealth":
|
||||||
from selenium_stealth import stealth
|
from selenium_stealth import stealth
|
||||||
|
@ -189,6 +190,7 @@ def load_chromdriver_normal(webdriver_path, driver_type, adblock_plus_enable):
|
||||||
renderer="Intel Iris OpenGL Engine",
|
renderer="Intel Iris OpenGL Engine",
|
||||||
fix_hairline=True,
|
fix_hairline=True,
|
||||||
)
|
)
|
||||||
|
#print("driver capabilities", driver.capabilities)
|
||||||
|
|
||||||
return driver
|
return driver
|
||||||
|
|
||||||
|
@ -199,6 +201,7 @@ def load_chromdriver_uc(webdriver_path, adblock_plus_enable):
|
||||||
|
|
||||||
options = uc.ChromeOptions()
|
options = uc.ChromeOptions()
|
||||||
options.page_load_strategy="eager"
|
options.page_load_strategy="eager"
|
||||||
|
|
||||||
#print("strategy", options.page_load_strategy)
|
#print("strategy", options.page_load_strategy)
|
||||||
|
|
||||||
if adblock_plus_enable:
|
if adblock_plus_enable:
|
||||||
|
@ -217,13 +220,19 @@ def load_chromdriver_uc(webdriver_path, adblock_plus_enable):
|
||||||
options.add_argument('--disable-translate')
|
options.add_argument('--disable-translate')
|
||||||
options.add_argument('--lang=zh-TW')
|
options.add_argument('--lang=zh-TW')
|
||||||
|
|
||||||
|
options.add_argument("--password-store=basic")
|
||||||
|
options.add_experimental_option("prefs", {"credentials_enable_service": False, "profile.password_manager_enabled": False})
|
||||||
|
|
||||||
|
caps = options.to_capabilities()
|
||||||
|
caps["unhandledPromptBehavior"] = u"accept"
|
||||||
|
|
||||||
driver = None
|
driver = None
|
||||||
if os.path.exists(chromedriver_path):
|
if os.path.exists(chromedriver_path):
|
||||||
print("Use user driver path:", chromedriver_path)
|
print("Use user driver path:", chromedriver_path)
|
||||||
#driver = uc.Chrome(service=chrome_service, options=options, suppress_welcome=False)
|
#driver = uc.Chrome(service=chrome_service, options=options, suppress_welcome=False)
|
||||||
is_local_chrome_browser_lower = False
|
is_local_chrome_browser_lower = False
|
||||||
try:
|
try:
|
||||||
driver = uc.Chrome(executable_path=chromedriver_path, options=options, suppress_welcome=False)
|
driver = uc.Chrome(executable_path=chromedriver_path, desired_capabilities=caps, suppress_welcome=False)
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
if "cannot connect to chrome" in str(exc):
|
if "cannot connect to chrome" in str(exc):
|
||||||
if "This version of ChromeDriver only supports Chrome version" in str(exc):
|
if "This version of ChromeDriver only supports Chrome version" in str(exc):
|
||||||
|
@ -238,7 +247,7 @@ def load_chromdriver_uc(webdriver_path, adblock_plus_enable):
|
||||||
else:
|
else:
|
||||||
print("Oops! web driver not on path:",chromedriver_path )
|
print("Oops! web driver not on path:",chromedriver_path )
|
||||||
print('let uc automatically download chromedriver.')
|
print('let uc automatically download chromedriver.')
|
||||||
driver = uc.Chrome(options=options, suppress_welcome=False)
|
driver = uc.Chrome(desired_capabilities=caps, suppress_welcome=False)
|
||||||
|
|
||||||
if driver is None:
|
if driver is None:
|
||||||
print("create web drive object fail!")
|
print("create web drive object fail!")
|
||||||
|
@ -250,6 +259,7 @@ def load_chromdriver_uc(webdriver_path, adblock_plus_enable):
|
||||||
}
|
}
|
||||||
#print("assign setDownloadBehavior.")
|
#print("assign setDownloadBehavior.")
|
||||||
driver.execute_cdp_cmd("Page.setDownloadBehavior", params)
|
driver.execute_cdp_cmd("Page.setDownloadBehavior", params)
|
||||||
|
#print("driver capabilities", driver.capabilities)
|
||||||
|
|
||||||
return driver
|
return driver
|
||||||
|
|
||||||
|
@ -1475,7 +1485,10 @@ def tixcraft_ticket_number_auto_fill(driver, select_obj, ticket_number):
|
||||||
|
|
||||||
return is_assign_ticket_number
|
return is_assign_ticket_number
|
||||||
|
|
||||||
def tixcraft_verify(driver, url):
|
def tixcraft_verify(driver):
|
||||||
|
show_debug_message = True # debug.
|
||||||
|
#show_debug_message = False # online
|
||||||
|
|
||||||
ret = False
|
ret = False
|
||||||
|
|
||||||
captcha_password_string = None
|
captcha_password_string = None
|
||||||
|
@ -1510,106 +1523,93 @@ def tixcraft_verify(driver, url):
|
||||||
html_text = html_text.replace(u'〗',u'】')
|
html_text = html_text.replace(u'〗',u'】')
|
||||||
html_text = html_text.replace(u']',u'】')
|
html_text = html_text.replace(u']',u'】')
|
||||||
|
|
||||||
#print("html_text:", html_text)
|
|
||||||
if u'【' in html_text and u'】' in html_text:
|
if u'【' in html_text and u'】' in html_text:
|
||||||
# PS: 這個太容易沖突,因為問題類型太多,不能直接使用。
|
# PS: 這個太容易沖突,因為問題類型太多,不能直接使用。
|
||||||
#captcha_password_string = find_between(html_text, u"【", u"】")
|
#captcha_password_string = find_between(html_text, u"【", u"】")
|
||||||
pass
|
pass
|
||||||
|
|
||||||
is_options_in_question = False
|
if show_debug_message:
|
||||||
answer_list, my_answer_delimitor = get_answer_list_by_question(html_text)
|
print("html_text:", html_text)
|
||||||
|
|
||||||
if u'請輸入"YES",代表您已詳閱且瞭解並同意' in html_text and u'實名制規則' in html_text:
|
is_options_in_question = False
|
||||||
|
|
||||||
|
# 請輸入"YES",代表您已詳閱且瞭解並同意。
|
||||||
|
if u'請輸入"YES"' in html_text:
|
||||||
|
if u'已詳閱' in html_text:
|
||||||
|
if u'並同意' in html_text:
|
||||||
captcha_password_string = 'YES'
|
captcha_password_string = 'YES'
|
||||||
|
|
||||||
if not captcha_password_string is None:
|
if show_debug_message:
|
||||||
|
print("captcha_password_string:", captcha_password_string)
|
||||||
|
|
||||||
|
|
||||||
form_input = None
|
form_input = None
|
||||||
try:
|
try:
|
||||||
form_input = driver.find_element(By.CSS_SELECTOR, '#checkCode')
|
form_input = driver.find_element(By.CSS_SELECTOR, '#checkCode')
|
||||||
if form_input is not None:
|
|
||||||
default_value = form_input.get_attribute('value')
|
|
||||||
if not default_value is None:
|
|
||||||
if len(default_value) == 0:
|
|
||||||
form_input.send_keys(captcha_password_string)
|
|
||||||
print("send captcha keys:" + captcha_password_string)
|
|
||||||
time.sleep(0.2)
|
|
||||||
ret = True
|
|
||||||
else:
|
|
||||||
print("find captcha input field fail")
|
|
||||||
|
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
print("find verify fail")
|
print("find verify code fail")
|
||||||
pass
|
pass
|
||||||
|
|
||||||
if ret:
|
default_value = None
|
||||||
form_input = None
|
if form_input is not None:
|
||||||
try:
|
try:
|
||||||
form_input = driver.find_element(By.CSS_SELECTOR, '#submitButton')
|
default_value = form_input.get_attribute('value')
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
|
print("find verify code fail")
|
||||||
|
pass
|
||||||
|
|
||||||
|
if default_value is None:
|
||||||
|
default_value = ""
|
||||||
|
|
||||||
|
if not captcha_password_string is None:
|
||||||
|
is_password_sent = False
|
||||||
|
if len(default_value)==0:
|
||||||
|
try:
|
||||||
|
# PS: sometime may send key twice...
|
||||||
|
form_input.clear()
|
||||||
|
|
||||||
|
form_input.send_keys(captcha_password_string)
|
||||||
|
is_password_sent = True
|
||||||
|
if show_debug_message:
|
||||||
|
print("sent password by bot.")
|
||||||
|
except Exception as exc:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if default_value == captcha_password_string:
|
||||||
|
if show_debug_message:
|
||||||
|
print("sent password by previous time.")
|
||||||
|
is_password_sent = True
|
||||||
|
|
||||||
|
if is_password_sent:
|
||||||
|
submit_btn = None
|
||||||
|
try:
|
||||||
|
submit_btn = driver.find_element(By.ID, 'submitButton')
|
||||||
|
except Exception as exc:
|
||||||
|
if show_debug_message:
|
||||||
print("find submit button fail")
|
print("find submit button fail")
|
||||||
print(exc)
|
print(exc)
|
||||||
pass
|
pass
|
||||||
|
|
||||||
# retry
|
|
||||||
is_submited = False
|
is_submited = False
|
||||||
|
if not submit_btn is None:
|
||||||
for i in range(3):
|
for i in range(3):
|
||||||
if form_input is not None:
|
|
||||||
is_visible = False
|
|
||||||
try:
|
try:
|
||||||
if form_input.is_enabled():
|
if submit_btn.is_enabled():
|
||||||
is_visible = True
|
submit_btn.click()
|
||||||
|
is_submited = True
|
||||||
|
if show_debug_message:
|
||||||
|
print("press submit button when time #", i+1)
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
if is_visible:
|
|
||||||
try:
|
|
||||||
form_input.click()
|
|
||||||
is_submited = True
|
|
||||||
except Exception as exc:
|
|
||||||
try:
|
|
||||||
driver.execute_script("arguments[0].click();", el)
|
|
||||||
is_submited = True
|
|
||||||
except Exception as exc:
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
print("find submit button none")
|
|
||||||
|
|
||||||
if is_submited:
|
if is_submited:
|
||||||
break
|
break
|
||||||
|
|
||||||
else:
|
|
||||||
is_auto_focus_enable = False
|
|
||||||
if not answer_list is None:
|
|
||||||
if len(answer_list) > 1:
|
|
||||||
is_auto_focus_enable = True
|
|
||||||
|
|
||||||
if u'請輸入玉山銀行信用卡' in html_text:
|
|
||||||
is_auto_focus_enable = True
|
|
||||||
|
|
||||||
if u'請輸入"YES"' in html_text:
|
|
||||||
is_auto_focus_enable = True
|
|
||||||
|
|
||||||
print("is_auto_focus_enable", is_auto_focus_enable)
|
|
||||||
if is_auto_focus_enable:
|
|
||||||
form_input = None
|
|
||||||
try:
|
|
||||||
form_input = driver.find_element(By.CSS_SELECTOR, '#checkCode')
|
|
||||||
if form_input is not None:
|
|
||||||
default_value = form_input.get_attribute('value')
|
|
||||||
is_need_focus = False
|
|
||||||
if default_value is None:
|
|
||||||
is_need_focus = True
|
|
||||||
else:
|
else:
|
||||||
if len(default_value)==0:
|
if len(default_value)==0:
|
||||||
is_need_focus = True
|
try:
|
||||||
if is_need_focus:
|
|
||||||
if form_input.is_enabled():
|
|
||||||
form_input.click()
|
form_input.click()
|
||||||
time.sleep(0.2)
|
time.sleep(0.5)
|
||||||
else:
|
|
||||||
print("find captcha input field fail")
|
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
print("find verify fail")
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
@ -1658,12 +1658,7 @@ def tixcraft_ticket_main(driver, config_dict):
|
||||||
if not is_assign_ticket_number:
|
if not is_assign_ticket_number:
|
||||||
# only this case:"ticket number changed by bot" to play sound!
|
# only this case:"ticket number changed by bot" to play sound!
|
||||||
# PS: I assume each time assign ticket number will succufully changed, so let sound play first.
|
# PS: I assume each time assign ticket number will succufully changed, so let sound play first.
|
||||||
play_captcha_sound = config_dict["advanced"]["play_captcha_sound"]["enable"]
|
check_and_play_sound_for_captcha(config_dict)
|
||||||
captcha_sound_filename = config_dict["advanced"]["play_captcha_sound"]["filename"].strip()
|
|
||||||
if play_captcha_sound:
|
|
||||||
app_root = get_app_root()
|
|
||||||
captcha_sound_filename = os.path.join(app_root, captcha_sound_filename)
|
|
||||||
play_mp3_async(captcha_sound_filename)
|
|
||||||
|
|
||||||
ticket_number = str(config_dict["ticket_number"])
|
ticket_number = str(config_dict["ticket_number"])
|
||||||
is_assign_ticket_number = tixcraft_ticket_number_auto_fill(driver, select_obj, ticket_number)
|
is_assign_ticket_number = tixcraft_ticket_number_auto_fill(driver, select_obj, ticket_number)
|
||||||
|
@ -1809,58 +1804,41 @@ def kktix_captcha_text_value(captcha_inner_div):
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
def kktix_input_captcha_text(captcha_inner_div, captcha_password_string, force_overwrite = False):
|
def kktix_input_captcha_text(captcha_password_input_tag, captcha_password_string, force_overwrite = False):
|
||||||
show_debug_message = True # debug.
|
show_debug_message = True # debug.
|
||||||
#show_debug_message = False # online
|
#show_debug_message = False # online
|
||||||
|
|
||||||
ret = False
|
is_cpatcha_sent = False
|
||||||
|
inputed_captcha_text = ""
|
||||||
|
|
||||||
captcha_password_text = None
|
if not captcha_password_input_tag is None:
|
||||||
|
if force_overwrite:
|
||||||
try:
|
try:
|
||||||
captcha_password_text = captcha_inner_div.find_element(By.TAG_NAME, "input")
|
captcha_password_input_tag.send_keys(captcha_password_string)
|
||||||
if show_debug_message:
|
print("send captcha keys:" + captcha_password_string)
|
||||||
print("found input field")
|
is_cpatcha_sent = True
|
||||||
|
inputed_captcha_text = captcha_password_string
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
pass
|
pass
|
||||||
|
else:
|
||||||
if not captcha_password_text is None:
|
# not force overwrite:
|
||||||
inputed_captcha_text = ""
|
inputed_captcha_text = None
|
||||||
try:
|
try:
|
||||||
inputed_captcha_text = captcha_password_text.get_attribute('value')
|
inputed_captcha_text = captcha_password_input_tag.get_attribute('value')
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
pass
|
pass
|
||||||
if inputed_captcha_text is None:
|
if inputed_captcha_text is None:
|
||||||
inputed_captcha_text = ""
|
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)
|
|
||||||
ret = True
|
|
||||||
else:
|
|
||||||
# not force overwrite:
|
|
||||||
if len(inputed_captcha_text) == 0:
|
|
||||||
captcha_password_text.send_keys(captcha_password_string)
|
|
||||||
print("send captcha keys:" + captcha_password_string)
|
|
||||||
ret = True
|
|
||||||
except Exception as exc:
|
|
||||||
if show_debug_message:
|
|
||||||
print("kktix_input_captcha_text Exception:")
|
|
||||||
print(exc)
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
# do focus()
|
|
||||||
if len(inputed_captcha_text) == 0:
|
if len(inputed_captcha_text) == 0:
|
||||||
try:
|
try:
|
||||||
print("focus() captcha to input.")
|
captcha_password_input_tag.send_keys(captcha_password_string)
|
||||||
captcha_password_text.click()
|
print("send captcha keys:" + captcha_password_string)
|
||||||
time.sleep(1)
|
is_cpatcha_sent = True
|
||||||
# let user to input answer, bot sleep 1 second.
|
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
return ret
|
return is_cpatcha_sent
|
||||||
|
|
||||||
def kktix_travel_price_list(driver, kktix_area_keyword, kktix_date_keyword):
|
def kktix_travel_price_list(driver, kktix_area_keyword, kktix_date_keyword):
|
||||||
show_debug_message = True # debug.
|
show_debug_message = True # debug.
|
||||||
|
@ -2069,7 +2047,7 @@ def kktix_assign_ticket_number(driver, ticket_number, kktix_area_auto_select_mod
|
||||||
|
|
||||||
return is_ticket_number_assigened
|
return is_ticket_number_assigened
|
||||||
|
|
||||||
def kktix_get_web_datetime(url, registrationsNewApp_div):
|
def kktix_get_web_datetime(registrationsNewApp_div):
|
||||||
show_debug_message = True # debug.
|
show_debug_message = True # debug.
|
||||||
show_debug_message = False # online
|
show_debug_message = False # online
|
||||||
|
|
||||||
|
@ -2221,7 +2199,7 @@ def kktix_check_register_status(url):
|
||||||
#print("registerStatus:", registerStatus)
|
#print("registerStatus:", registerStatus)
|
||||||
return registerStatus
|
return registerStatus
|
||||||
|
|
||||||
def kktix_reg_new_captcha(driver, captcha_inner_div, auto_guess_options):
|
def kktix_reg_new_captcha(registrationsNewApp_div, captcha_inner_div, auto_guess_options):
|
||||||
show_debug_message = True # debug.
|
show_debug_message = True # debug.
|
||||||
show_debug_message = False # online
|
show_debug_message = False # online
|
||||||
|
|
||||||
|
@ -2349,7 +2327,7 @@ def kktix_reg_new_captcha(driver, captcha_inner_div, auto_guess_options):
|
||||||
|
|
||||||
if is_need_parse_web_datetime:
|
if is_need_parse_web_datetime:
|
||||||
captcha_password_string = None
|
captcha_password_string = None
|
||||||
web_datetime = kktix_get_web_datetime(url, registrationsNewApp_div)
|
web_datetime = kktix_get_web_datetime(registrationsNewApp_div)
|
||||||
if not web_datetime is None:
|
if not web_datetime is None:
|
||||||
if show_debug_message:
|
if show_debug_message:
|
||||||
print("web_datetime:", web_datetime)
|
print("web_datetime:", web_datetime)
|
||||||
|
@ -2473,7 +2451,7 @@ def kktix_reg_new_captcha(driver, captcha_inner_div, auto_guess_options):
|
||||||
#print("is_need_parse_web_time", is_need_parse_web_time)
|
#print("is_need_parse_web_time", is_need_parse_web_time)
|
||||||
if is_need_parse_web_time:
|
if is_need_parse_web_time:
|
||||||
captcha_password_string = None
|
captcha_password_string = None
|
||||||
web_datetime = kktix_get_web_datetime(url, registrationsNewApp_div)
|
web_datetime = kktix_get_web_datetime(registrationsNewApp_div)
|
||||||
if not web_datetime is None:
|
if not web_datetime is None:
|
||||||
tmp_text = captcha_text_div_text
|
tmp_text = captcha_text_div_text
|
||||||
# replace ex.
|
# replace ex.
|
||||||
|
@ -2581,14 +2559,11 @@ def kktix_reg_new_captcha(driver, captcha_inner_div, auto_guess_options):
|
||||||
if show_debug_message:
|
if show_debug_message:
|
||||||
print("captcha_password_string:", captcha_password_string)
|
print("captcha_password_string:", captcha_password_string)
|
||||||
|
|
||||||
# ask question.
|
# still no answer.
|
||||||
|
if captcha_password_string is None:
|
||||||
if auto_guess_options:
|
if auto_guess_options:
|
||||||
if not is_combine_two_question:
|
if not is_combine_two_question:
|
||||||
if captcha_password_string is None:
|
|
||||||
answer_list, my_answer_delimitor = get_answer_list_by_question(captcha_text_div_text)
|
answer_list, my_answer_delimitor = get_answer_list_by_question(captcha_text_div_text)
|
||||||
else:
|
|
||||||
# no need guess options.
|
|
||||||
pass
|
|
||||||
|
|
||||||
return captcha_password_string, answer_list, my_answer_delimitor
|
return captcha_password_string, answer_list, my_answer_delimitor
|
||||||
|
|
||||||
|
@ -2659,14 +2634,25 @@ def kktix_reg_new_main(driver, answer_index, is_finish_checkbox_click, config_di
|
||||||
is_captcha_appear_and_filled_password = False
|
is_captcha_appear_and_filled_password = False
|
||||||
answer_list = None
|
answer_list = None
|
||||||
|
|
||||||
if is_assign_ticket_number:
|
|
||||||
# TODO: in guess options mode, no need to travel div again.
|
# TODO: in guess options mode, no need to travel div again.
|
||||||
captcha_inner_div = None
|
captcha_inner_div = None
|
||||||
|
|
||||||
|
if is_assign_ticket_number:
|
||||||
try:
|
try:
|
||||||
captcha_inner_div = driver.find_element(By.CSS_SELECTOR, '.custom-captcha-inner')
|
captcha_inner_div = driver.find_element(By.CSS_SELECTOR, '.custom-captcha-inner')
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
captcha_password_input_tag = None
|
||||||
|
if not captcha_inner_div is None:
|
||||||
|
try:
|
||||||
|
captcha_password_input_tag = captcha_inner_div.find_element(By.TAG_NAME, "input")
|
||||||
|
if show_debug_message:
|
||||||
|
print("found captcha input field")
|
||||||
|
except Exception as exc:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if not captcha_password_input_tag is None:
|
||||||
captcha_password_string = None
|
captcha_password_string = None
|
||||||
if captcha_inner_div is not None:
|
if captcha_inner_div is not None:
|
||||||
is_captcha_appear = True
|
is_captcha_appear = True
|
||||||
|
@ -2674,12 +2660,39 @@ def kktix_reg_new_main(driver, answer_index, is_finish_checkbox_click, config_di
|
||||||
print("found captcha_inner_div layor.")
|
print("found captcha_inner_div layor.")
|
||||||
|
|
||||||
auto_guess_options = config_dict["kktix"]["auto_guess_options"]
|
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)
|
captcha_password_string, answer_list, my_answer_delimitor = kktix_reg_new_captcha(registrationsNewApp_div, captcha_inner_div, auto_guess_options)
|
||||||
|
|
||||||
|
if captcha_password_string is not None:
|
||||||
# password is not None, try to send.
|
# password is not None, try to send.
|
||||||
# password is None, focus to input.
|
is_cpatcha_sent = kktix_input_captcha_text(captcha_password_input_tag, captcha_password_string)
|
||||||
if kktix_input_captcha_text(captcha_inner_div, captcha_password_string):
|
if is_cpatcha_sent:
|
||||||
is_captcha_appear_and_filled_password = True
|
is_captcha_appear_and_filled_password = True
|
||||||
|
else:
|
||||||
|
is_try_to_focus = False
|
||||||
|
if answer_list is None:
|
||||||
|
is_try_to_focus = True
|
||||||
|
else:
|
||||||
|
if len(answer_list)==0:
|
||||||
|
is_try_to_focus = True
|
||||||
|
|
||||||
|
if is_try_to_focus:
|
||||||
|
# password is None, focus to input, and play sound.
|
||||||
|
inputed_captcha_text = None
|
||||||
|
try:
|
||||||
|
inputed_captcha_text = captcha_password_input_tag.get_attribute('value')
|
||||||
|
except Exception as exc:
|
||||||
|
pass
|
||||||
|
if inputed_captcha_text is None:
|
||||||
|
inputed_captcha_text = ""
|
||||||
|
if len(inputed_captcha_text) == 0:
|
||||||
|
try:
|
||||||
|
print("focus() captcha to input.")
|
||||||
|
check_and_play_sound_for_captcha(config_dict)
|
||||||
|
captcha_password_input_tag.click()
|
||||||
|
time.sleep(1)
|
||||||
|
# let user to input answer, bot sleep 1 second.
|
||||||
|
except Exception as exc:
|
||||||
|
pass
|
||||||
|
|
||||||
if show_debug_message:
|
if show_debug_message:
|
||||||
print("is_captcha_appear:", is_captcha_appear)
|
print("is_captcha_appear:", is_captcha_appear)
|
||||||
|
@ -2720,7 +2733,7 @@ def kktix_reg_new_main(driver, answer_index, is_finish_checkbox_click, config_di
|
||||||
unique = [x for i, x in enumerate(answer_list) if answer_list.index(x) == i]
|
unique = [x for i, x in enumerate(answer_list) if answer_list.index(x) == i]
|
||||||
answer_list = unique
|
answer_list = unique
|
||||||
|
|
||||||
# start to try answer.
|
# start to try answers.
|
||||||
if not answer_list is None:
|
if not answer_list is None:
|
||||||
# for popular event
|
# for popular event
|
||||||
if len(answer_list) > 0:
|
if len(answer_list) > 0:
|
||||||
|
@ -2734,9 +2747,10 @@ def kktix_reg_new_main(driver, answer_index, is_finish_checkbox_click, config_di
|
||||||
answer = answer[:-1]
|
answer = answer[:-1]
|
||||||
|
|
||||||
if len(answer) > 0:
|
if len(answer) > 0:
|
||||||
print("send ans:" + answer)
|
print("send answer:" + answer)
|
||||||
captcha_password_string = answer
|
each_password_string = answer
|
||||||
if kktix_input_captcha_text(captcha_inner_div, captcha_password_string):
|
is_cpatcha_sent = kktix_input_captcha_text(captcha_password_input_tag, each_password_string)
|
||||||
|
if is_cpatcha_sent:
|
||||||
kktix_press_next_button(driver)
|
kktix_press_next_button(driver)
|
||||||
else:
|
else:
|
||||||
# exceed index, do nothing.
|
# exceed index, do nothing.
|
||||||
|
@ -3334,7 +3348,7 @@ def urbtix_performance(driver, config_dict):
|
||||||
# True: area block appear.
|
# True: area block appear.
|
||||||
# False: area block not appear.
|
# False: area block not appear.
|
||||||
# ps: return value for date auto select.
|
# ps: return value for date auto select.
|
||||||
def cityline_area_auto_select(driver, kktix_area_keyword):
|
def cityline_area_auto_select(driver, kktix_area_keyword, kktix_date_keyword):
|
||||||
ret = False
|
ret = False
|
||||||
areas = None
|
areas = None
|
||||||
|
|
||||||
|
@ -3487,91 +3501,59 @@ def cityline_area_selected_text(driver):
|
||||||
|
|
||||||
|
|
||||||
def cityline_ticket_number_auto_select(driver, ticket_number):
|
def cityline_ticket_number_auto_select(driver, ticket_number):
|
||||||
ret = False
|
show_debug_message = True # debug.
|
||||||
is_assign_ticket_number = False
|
show_debug_message = False # online
|
||||||
selected_value = ""
|
|
||||||
|
|
||||||
el = None
|
form_select = None
|
||||||
try:
|
try:
|
||||||
el = driver.find_element(By.CSS_SELECTOR, 'td.tix_type_select > div.chzn-container > a > span')
|
form_select = driver.find_element(By.CSS_SELECTOR, 'select.select-num')
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
#print("find ticket_number select fail")
|
if show_debug_message:
|
||||||
#print(exc)
|
print("find ticket_number select fail")
|
||||||
|
print(exc)
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
select_obj = None
|
||||||
|
if form_select is not None:
|
||||||
is_visible = False
|
is_visible = False
|
||||||
if el is not None:
|
|
||||||
try:
|
try:
|
||||||
if el.is_enabled():
|
is_visible = form_select.is_enabled()
|
||||||
is_visible = True
|
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
selected_value = None
|
|
||||||
if is_visible:
|
if is_visible:
|
||||||
ret = True
|
|
||||||
selected_value = ""
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
selected_value = el.text
|
select_obj = Select(form_select)
|
||||||
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:
|
except Exception as exc:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
is_options_enabled = False
|
is_assign_ticket_number = False
|
||||||
el_options = None
|
if not select_obj is None:
|
||||||
|
row_text = None
|
||||||
try:
|
try:
|
||||||
el_options = driver.find_element(By.CSS_SELECTOR, 'td.tix_type_select > div.chzn-container > div.chzn-drop')
|
row_text = select_obj.first_selected_option.text
|
||||||
if el_options is not None:
|
|
||||||
if el_options.is_enabled():
|
|
||||||
is_options_enabled = True
|
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
pass
|
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:
|
if not row_text is None:
|
||||||
if row_text == ticket_number:
|
if len(row_text) > 0:
|
||||||
print("row_text clicked:", row_text)
|
if row_text != "0":
|
||||||
row.click()
|
# ticket assign.
|
||||||
is_assign_ticket_number = True
|
is_assign_ticket_number = True
|
||||||
break
|
|
||||||
except Exception as exc:
|
|
||||||
pass
|
|
||||||
|
|
||||||
return ret, is_assign_ticket_number
|
if not is_assign_ticket_number:
|
||||||
|
is_assign_ticket_number = tixcraft_ticket_number_auto_fill(driver, select_obj, ticket_number)
|
||||||
|
else:
|
||||||
|
if show_debug_message:
|
||||||
|
print("ticket_number assigned by previous action.")
|
||||||
|
|
||||||
|
return is_assign_ticket_number
|
||||||
|
|
||||||
|
|
||||||
def cityline_next_button_press(driver):
|
def cityline_next_button_press(driver):
|
||||||
ret = False
|
ret = False
|
||||||
try:
|
try:
|
||||||
time.sleep(0.2)
|
|
||||||
el = driver.find_element(By.CSS_SELECTOR, '#expressPurchaseButton')
|
el = driver.find_element(By.CSS_SELECTOR, '#expressPurchaseButton')
|
||||||
if el is not None:
|
if el is not None:
|
||||||
ret = True
|
|
||||||
print("bingo, found next button")
|
print("bingo, found next button")
|
||||||
|
|
||||||
if el.is_enabled():
|
if el.is_enabled():
|
||||||
el.click()
|
el.click()
|
||||||
ret = True
|
ret = True
|
||||||
|
@ -3581,103 +3563,37 @@ def cityline_next_button_press(driver):
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
def cityline_event(driver):
|
|
||||||
ret = False
|
|
||||||
|
|
||||||
is_non_member_displayed = False
|
def cityline_performance(driver, config_dict):
|
||||||
|
show_debug_message = True # debug.
|
||||||
try:
|
#show_debug_message = False # online
|
||||||
el_non_member = driver.find_element(By.ID, 'buyBtWalkIn')
|
|
||||||
if el_non_member is not None:
|
|
||||||
if el_non_member.is_enabled():
|
|
||||||
#if el_non_member.is_displayed():
|
|
||||||
is_non_member_displayed = True
|
|
||||||
except Exception as exc:
|
|
||||||
#print(exc)
|
|
||||||
pass
|
|
||||||
|
|
||||||
try:
|
|
||||||
el = driver.find_element(By.ID, 'buyBt')
|
|
||||||
if el is not None:
|
|
||||||
if el.is_enabled():
|
|
||||||
#if el.is_displayed():
|
|
||||||
# for non-member
|
|
||||||
#javascript:selectPerformance(1);
|
|
||||||
# for member
|
|
||||||
#javascript:selectPerformance(0);
|
|
||||||
|
|
||||||
if not is_non_member_displayed:
|
|
||||||
# when two buttons appear, do nothing.
|
|
||||||
el.click()
|
|
||||||
except Exception as exc:
|
|
||||||
#print("find next button fail")
|
|
||||||
#print(exc)
|
|
||||||
pass
|
|
||||||
|
|
||||||
return ret
|
|
||||||
|
|
||||||
def cityline_captcha_auto_focus(driver):
|
|
||||||
ret = False
|
|
||||||
try:
|
|
||||||
el = driver.find_element(By.CSS_SELECTOR, 'input[name=verify]')
|
|
||||||
if el is not None:
|
|
||||||
if el.is_enabled():
|
|
||||||
inputed_text = el.get_attribute('value')
|
|
||||||
if not inputed_text is None:
|
|
||||||
if len(inputed_text) == 0:
|
|
||||||
#print("click the input text")
|
|
||||||
el.click()
|
|
||||||
ret = True
|
|
||||||
else:
|
|
||||||
#print("element is not enable")
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
print("element is None")
|
|
||||||
except Exception as exc:
|
|
||||||
print("find verify text fail")
|
|
||||||
print(exc)
|
|
||||||
pass
|
|
||||||
|
|
||||||
# make captcha image bigger/
|
|
||||||
if ret:
|
|
||||||
try:
|
|
||||||
el = driver.find_element(By.CSS_SELECTOR, '#captchaImage')
|
|
||||||
if el is not None:
|
|
||||||
if el.is_enabled():
|
|
||||||
image_width = el.get_attribute('width')
|
|
||||||
#print("image_width:", image_width)
|
|
||||||
if image_width != 200:
|
|
||||||
driver.execute_script("document.getElementById(\"captchaImage\").width=200;")
|
|
||||||
except Exception as exc:
|
|
||||||
print("excute script resize fail")
|
|
||||||
print(exc)
|
|
||||||
pass
|
|
||||||
|
|
||||||
return ret
|
|
||||||
|
|
||||||
|
|
||||||
def cityline_performance(driver, url, config_dict):
|
|
||||||
is_assign_ticket_number = False
|
|
||||||
|
|
||||||
if "performance.do;" in url:
|
|
||||||
cityline_captcha_auto_focus(driver)
|
|
||||||
|
|
||||||
kktix_area_keyword = config_dict["kktix"]["area_keyword"].strip()
|
|
||||||
|
|
||||||
auto_fill_ticket_number = config_dict["kktix"]["auto_fill_ticket_number"]
|
auto_fill_ticket_number = config_dict["kktix"]["auto_fill_ticket_number"]
|
||||||
if "?cid=" in url:
|
|
||||||
if auto_fill_ticket_number:
|
if auto_fill_ticket_number:
|
||||||
|
# click price row.
|
||||||
area_div_exist = False
|
area_div_exist = False
|
||||||
|
kktix_area_keyword = config_dict["kktix"]["area_keyword"].strip()
|
||||||
|
kktix_date_keyword = config_dict["kktix"]["date_keyword"].strip()
|
||||||
if len(kktix_area_keyword) > 0:
|
if len(kktix_area_keyword) > 0:
|
||||||
area_div_exist = cityline_area_auto_select(driver, kktix_area_keyword)
|
#area_div_exist = cityline_area_auto_select(driver, kktix_area_keyword, kktix_date_keyword)
|
||||||
|
pass
|
||||||
|
|
||||||
|
if show_debug_message:
|
||||||
|
print("kktix_area_keyword:", kktix_area_keyword)
|
||||||
|
print("kktix_date_keyword:", kktix_date_keyword)
|
||||||
|
|
||||||
|
# choose ticket.
|
||||||
ticket_number = str(config_dict["ticket_number"])
|
ticket_number = str(config_dict["ticket_number"])
|
||||||
ticket_number_select_exist, is_assign_ticket_number = cityline_ticket_number_auto_select(driver, ticket_number)
|
is_assign_ticket_number = cityline_ticket_number_auto_select(driver, ticket_number)
|
||||||
|
|
||||||
# todo.
|
if show_debug_message:
|
||||||
|
print("ticket_number:", ticket_number)
|
||||||
|
print("is_assign_ticket_number:", is_assign_ticket_number)
|
||||||
|
|
||||||
|
is_assign_ticket_number = False
|
||||||
|
if is_assign_ticket_number:
|
||||||
auto_press_next_step_button = config_dict["kktix"]["auto_press_next_step_button"]
|
auto_press_next_step_button = config_dict["kktix"]["auto_press_next_step_button"]
|
||||||
if auto_press_next_step_button:
|
if auto_press_next_step_button:
|
||||||
if is_assign_ticket_number:
|
|
||||||
selected_text = cityline_area_selected_text(driver)
|
selected_text = cityline_area_selected_text(driver)
|
||||||
if not selected_text is None:
|
if not selected_text is None:
|
||||||
if kktix_area_keyword in selected_text:
|
if kktix_area_keyword in selected_text:
|
||||||
|
@ -3751,6 +3667,14 @@ def facebook_login(driver, facebook_account):
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
def check_and_play_sound_for_captcha(config_dict):
|
||||||
|
play_captcha_sound = config_dict["advanced"]["play_captcha_sound"]["enable"]
|
||||||
|
captcha_sound_filename = config_dict["advanced"]["play_captcha_sound"]["filename"].strip()
|
||||||
|
if play_captcha_sound:
|
||||||
|
app_root = get_app_root()
|
||||||
|
captcha_sound_filename = os.path.join(app_root, captcha_sound_filename)
|
||||||
|
play_mp3_async(captcha_sound_filename)
|
||||||
|
|
||||||
def play_mp3_async(sound_filename):
|
def play_mp3_async(sound_filename):
|
||||||
import threading
|
import threading
|
||||||
threading.Thread(target=play_mp3, args=(sound_filename,), daemon=True).start()
|
threading.Thread(target=play_mp3, args=(sound_filename,), daemon=True).start()
|
||||||
|
@ -3815,6 +3739,13 @@ def check_pop_alert(driver):
|
||||||
|
|
||||||
return is_alert_popup
|
return is_alert_popup
|
||||||
|
|
||||||
|
def list_all_cookies(driver):
|
||||||
|
all_cookies=driver.get_cookies();
|
||||||
|
cookies_dict = {}
|
||||||
|
for cookie in all_cookies:
|
||||||
|
cookies_dict[cookie['name']] = cookie['value']
|
||||||
|
print(cookies_dict)
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
config_dict = get_config_dict()
|
config_dict = get_config_dict()
|
||||||
|
|
||||||
|
@ -3875,13 +3806,14 @@ def main():
|
||||||
is_verifyCode_editing = False
|
is_verifyCode_editing = False
|
||||||
|
|
||||||
print('UnexpectedAlertPresentException at this url:', url )
|
print('UnexpectedAlertPresentException at this url:', url )
|
||||||
time.sleep(3.5)
|
#time.sleep(3.5)
|
||||||
|
|
||||||
# PS: do nothing...
|
# PS: do nothing...
|
||||||
# PS: current chrome-driver + chrome call current_url cause alert/prompt dialog disappear!
|
# PS: current chrome-driver + chrome call current_url cause alert/prompt dialog disappear!
|
||||||
# raise exception at selenium/webdriver/remote/errorhandler.py
|
# raise exception at selenium/webdriver/remote/errorhandler.py
|
||||||
# after dialog disappear new excpetion: unhandled inspector error: Not attached to an active page
|
# after dialog disappear new excpetion: unhandled inspector error: Not attached to an active page
|
||||||
is_pass_alert = False
|
is_pass_alert = False
|
||||||
|
is_pass_alert = True
|
||||||
if is_pass_alert:
|
if is_pass_alert:
|
||||||
try:
|
try:
|
||||||
driver.switch_to.alert.accept()
|
driver.switch_to.alert.accept()
|
||||||
|
@ -3950,7 +3882,7 @@ def main():
|
||||||
|
|
||||||
# for Max's manuall test.
|
# for Max's manuall test.
|
||||||
if '/Downloads/varify.html' in url:
|
if '/Downloads/varify.html' in url:
|
||||||
tixcraft_verify(driver, url)
|
tixcraft_verify(driver)
|
||||||
|
|
||||||
tixcraft_family = False
|
tixcraft_family = False
|
||||||
if 'tixcraft.com' in url:
|
if 'tixcraft.com' in url:
|
||||||
|
@ -3997,7 +3929,7 @@ def main():
|
||||||
tixcraft_area_auto_select(driver, url, config_dict)
|
tixcraft_area_auto_select(driver, url, config_dict)
|
||||||
|
|
||||||
if '/ticket/verify/' in url:
|
if '/ticket/verify/' in url:
|
||||||
tixcraft_verify(driver, url)
|
tixcraft_verify(driver)
|
||||||
|
|
||||||
# main app, to select ticket number.
|
# main app, to select ticket number.
|
||||||
if '/ticket/ticket/' in url:
|
if '/ticket/ticket/' in url:
|
||||||
|
@ -4068,19 +4000,13 @@ def main():
|
||||||
urbtix_performance(driver, config_dict)
|
urbtix_performance(driver, config_dict)
|
||||||
|
|
||||||
if 'cityline.com' in url:
|
if 'cityline.com' in url:
|
||||||
if '/event.do' in url:
|
# https://www.cityline.com/Login.html?targetUrl=https%3A%2F%2F
|
||||||
cityline_event(driver)
|
# ignore url redirect
|
||||||
#pass
|
if '/Login.html' in url:
|
||||||
|
continue
|
||||||
|
|
||||||
if '/Events.do' in url:
|
if '/internet/performance?' in url:
|
||||||
if len(driver.window_handles) == 2:
|
cityline_performance(driver, config_dict)
|
||||||
try:
|
|
||||||
driver.close()
|
|
||||||
except Exception as excCloseFail:
|
|
||||||
pass
|
|
||||||
|
|
||||||
if '/performance.do' in url:
|
|
||||||
cityline_performance(driver, url, config_dict)
|
|
||||||
|
|
||||||
# for facebook
|
# for facebook
|
||||||
facebook_login_url = 'https://www.facebook.com/login.php?'
|
facebook_login_url = 'https://www.facebook.com/login.php?'
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
{"tixcraft": {"pass_1_seat_remaining": true, "area_auto_select": {"enable": true, "area_keyword": "", "mode": "from top to bottom", "area_keyword_4": "", "area_keyword_1": "", "area_keyword_2": "", "area_keyword_3": ""}, "auto_reload_coming_soon_page": true, "date_auto_select": {"enable": true, "date_keyword": "", "mode": "from top to bottom"}, "pass_date_is_sold_out": true}, "homepage1": "https://kktix.com", "language": "\u7e41\u9ad4\u4e2d\u6587", "homepage2": "https://tixcraft.com", "kktix": {"auto_guess_options": true, "answer_dictionary": "", "area_keyword": "", "auto_press_next_step_button": true, "area_mode": "from top to bottom", "auto_fill_ticket_number": true, "auto_fill_ticket_price": "$1,500", "date_keyword": ""}, "facebook_account": "", "browser1": "chrome", "browser2": "firefox", "debug": false, "ticket_number": 2, "homepage": "https://tixcraft.com", "browser": "chrome", "advanced": {"play_captcha_sound": {"enable": true, "filename": "ding-dong.mp3"}, "facebook_account": ""}}
|
{"tixcraft": {"pass_1_seat_remaining": true, "area_auto_select": {"enable": true, "area_keyword": "", "mode": "from top to bottom", "area_keyword_4": "", "area_keyword_1": "", "area_keyword_2": "", "area_keyword_3": ""}, "auto_reload_coming_soon_page": true, "date_auto_select": {"enable": true, "date_keyword": "", "mode": "from top to bottom"}, "pass_date_is_sold_out": true}, "homepage1": "https://kktix.com", "language": "\u7e41\u9ad4\u4e2d\u6587", "homepage2": "https://tixcraft.com", "kktix": {"auto_guess_options": true, "answer_dictionary": "", "area_keyword": "", "auto_press_next_step_button": true, "area_mode": "from top to bottom", "auto_fill_ticket_number": true, "auto_fill_ticket_price": "$1,500", "date_keyword": ""}, "facebook_account": "", "browser1": "chrome", "browser2": "firefox", "debug": false, "ticket_number": 2, "homepage": "https://kktix.com", "browser": "chrome", "advanced": {"play_captcha_sound": {"enable": true, "filename": "ding-dong.wav"}, "facebook_account": "", "adblock_plus_enable": false}}
|
|
@ -19,7 +19,7 @@ import json
|
||||||
import webbrowser
|
import webbrowser
|
||||||
import pyperclip
|
import pyperclip
|
||||||
|
|
||||||
CONST_APP_VERSION = u"MaxBot (2022.11.19)"
|
CONST_APP_VERSION = u"MaxBot (2022.11.20)"
|
||||||
|
|
||||||
CONST_FROM_TOP_TO_BOTTOM = u"from top to bottom"
|
CONST_FROM_TOP_TO_BOTTOM = u"from top to bottom"
|
||||||
CONST_FROM_BOTTOM_TO_TOP = u"from bottom to top"
|
CONST_FROM_BOTTOM_TO_TOP = u"from bottom to top"
|
||||||
|
|
Loading…
Reference in New Issue