reformat code, and use global variable

master
CHUN YU YAO 2022-01-13 01:14:27 +08:00
parent 1820d5e817
commit 4f9d29d9e0
2 changed files with 408 additions and 315 deletions

View File

@ -27,13 +27,6 @@ from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
# for selenium 4
from selenium.webdriver.chrome.service import Service
# method 5: uc
#import undetected_chromedriver as uc
# method 6: Selenium Stealth
from selenium_stealth import stealth
# for wait #1
import time
@ -54,12 +47,11 @@ warnings.simplefilter('ignore',InsecureRequestWarning)
import ssl
ssl._create_default_https_context = ssl._create_unverified_context
#執行方式python chrome_tixcraft.py 或 python3 chrome_tixcraft.py
#附註1沒有寫的很好很多地方應該可以模組化。
#附註2
CONST_APP_VERSION = u"MaxBot (2022.01.10)"
CONST_APP_VERSION = u"MaxBot (2022.01.12)"
CONST_FROM_TOP_TO_BOTTOM = u"from top to bottom"
CONST_FROM_BOTTOM_TO_TOP = u"from bottom to top"
@ -74,20 +66,6 @@ CONT_STRING_1_SEATS_REMAINING = [u'1 seat(s) remaining',u'剩餘 1',u'1 席残
# 說明:初始化 webdriver
driver = None
# 讀取檔案裡的參數值
basis = ""
if hasattr(sys, 'frozen'):
basis = sys.executable
else:
basis = sys.argv[0]
app_root = os.path.dirname(basis)
config_filepath = os.path.join(app_root, 'settings.json')
config_dict = None
if os.path.isfile(config_filepath):
with open(config_filepath) as json_data:
config_dict = json.load(json_data)
homepage = None
browser = None
ticket_number = None
@ -120,6 +98,57 @@ auto_guess_options = False
debugMode = False
def get_app_root():
# 讀取檔案裡的參數值
basis = ""
if hasattr(sys, 'frozen'):
basis = sys.executable
else:
basis = sys.argv[0]
app_root = os.path.dirname(basis)
return app_root
def get_config_dict():
config_json_filename = 'settings.json'
app_root = get_app_root()
config_filepath = os.path.join(app_root, config_json_filename)
config_dict = None
if os.path.isfile(config_filepath):
with open(config_filepath) as json_data:
config_dict = json.load(json_data)
return config_dict
def load_config_from_local(driver):
config_dict = get_config_dict()
global homepage
global browser
global debugMode
global ticket_number
global facebook_account
global auto_press_next_step_button
global auto_fill_ticket_number
global kktix_area_auto_select_mode
global kktix_area_keyword
global kktix_answer_dictionary
global kktix_answer_dictionary_list
global auto_guess_options
global pass_1_seat_remaining_enable
global area_keyword_1
global area_keyword_2
global date_auto_select_enable
global date_auto_select_mode
global date_keyword
global area_auto_select_enable
global area_auto_select_mode
global debugMode
if not config_dict is None:
# read config.
if 'homepage' in config_dict:
@ -249,6 +278,12 @@ if not config_dict is None:
Root_Dir = ""
if browser == "chrome":
# method 5: uc
#import undetected_chromedriver as uc
# method 6: Selenium Stealth
from selenium_stealth import stealth
DEFAULT_ARGS = [
'--disable-audio-output',
'--disable-background-networking',
@ -376,6 +411,7 @@ if not config_dict is None:
chromedriver_path =Root_Dir+ "webdriver/geckodriver"
if platform.system()=="windows":
chromedriver_path =Root_Dir+ "webdriver/geckodriver.exe"
firefox_service = Service(chromedriver_path)
driver = webdriver.Firefox(service=firefox_service)
@ -389,9 +425,12 @@ if not config_dict is None:
except Exception as excSwithFail:
pass
driver.get(homepage)
else:
print("Config error!")
return driver
# common functions.
def find_between( s, first, last ):
try:
@ -737,7 +776,7 @@ def get_answer_list_by_question(captcha_text_div_text):
return return_list, my_answer_delimitor
# from detail to game
def tixcraft_redirect(url):
def tixcraft_redirect(driver, url):
game_name = ""
# get game_name from url
@ -752,7 +791,10 @@ def tixcraft_redirect(url):
#entry_url = "tixcraft.com/activity/game/%s" % (game_name,)
driver.get(entry_url)
def date_auto_select(url):
def date_auto_select(driver, url, date_auto_select_mode, date_keyword):
debug_date_select = True # debug.
debug_date_select = False # online
game_name = ""
if "/activity/game/" in url:
@ -760,9 +802,18 @@ def date_auto_select(url):
if len(url_split) >= 6:
game_name = url_split[5]
if debug_date_select:
print('get date game_name:', game_name)
print("date_auto_select_mode:", date_auto_select_mode)
print("date_keyword:", date_keyword)
# choose date
if "/activity/game/%s" % (game_name,) in url:
if len(date_keyword) == 0:
if debug_date_select:
print("date keyword is empty.")
el = None
if date_auto_select_mode == CONST_FROM_TOP_TO_BOTTOM:
@ -781,6 +832,9 @@ def date_auto_select(url):
pass
#print("find a tag fail")
if debug_date_select:
print("date keyword is empty.")
if el is not None:
# first date.
try:
@ -788,6 +842,9 @@ def date_auto_select(url):
except Exception as exc:
print("try to click .btn-next fail")
else:
if debug_date_select:
print("date keyword:", date_keyword)
# match keyword.
date_list = None
try:
@ -930,7 +987,7 @@ def get_tixcraft_target_area(el, area_keyword):
# PS: auto refresh condition 1: no keyword + no hyperlink.
# PS: auto refresh condition 2: with keyword + no hyperlink.
def area_auto_select(url):
def area_auto_select(driver, url, area_keyword_1, area_keyword_2):
if '/ticket/area/' in url:
#driver.switch_to.default_content()
@ -1117,7 +1174,7 @@ def ticket_number_auto_fill(url, form_select):
except Exception as exc:
print("find form_verifyCode fail")
def tixcraft_verify(url):
def tixcraft_verify(driver, url):
ret = False
captcha_password_string = None
@ -1248,7 +1305,7 @@ def tixcraft_verify(url):
return ret
def tixcraft_ticket_main(url, is_verifyCode_editing):
def tixcraft_ticket_main(driver, url, is_verifyCode_editing):
form_select = None
try:
#form_select = driver.find_element(By.TAG_NAME, 'select')
@ -1292,7 +1349,7 @@ def tixcraft_ticket_main(url, is_verifyCode_editing):
# : 1: /events/xxx
# : 2: /events/xxx/registrations/new
# : This is for case-1.
def kktix_events_press_next_button():
def kktix_events_press_next_button(driver):
ret = False
# let javascript to enable button.
@ -1309,7 +1366,7 @@ def kktix_events_press_next_button():
except Exception as exc:
print("wait form-actions div wait to be clickable Exception:")
print(exc)
#print(exc)
pass
# retry once
@ -1328,7 +1385,7 @@ def kktix_events_press_next_button():
return ret
# : This is for case-2 next button.
def kktix_press_next_button():
def kktix_press_next_button(driver):
ret = False
# let javascript to enable button.
@ -1424,7 +1481,7 @@ def kktix_input_captcha_text(captcha_inner_div, captcha_password_string, force_o
return ret
def kktix_assign_ticket_number():
def kktix_assign_ticket_number(driver, ticket_number, kktix_area_keyword):
ret = False
areas = None
@ -1598,7 +1655,7 @@ def kktix_get_web_datetime(url, registrationsNewApp_div):
return web_datetime
def kktix_check_agree_checkbox():
def kktix_check_agree_checkbox(driver):
is_need_refresh = False
is_finish_checkbox_click = False
@ -1679,14 +1736,14 @@ 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):
def kktix_reg_new_main(url, answer_index, registrationsNewApp_div, is_finish_checkbox_click, auto_fill_ticket_number, ticket_number, kktix_area_keyword):
#---------------------------
# part 2: ticket number
#---------------------------
is_assign_ticket_number = False
if auto_fill_ticket_number:
for retry_index in range(10):
is_assign_ticket_number = kktix_assign_ticket_number()
is_assign_ticket_number = kktix_assign_ticket_number(driver, ticket_number, kktix_area_keyword)
if is_assign_ticket_number:
break
#print('is_assign_ticket_number:', is_assign_ticket_number)
@ -2065,7 +2122,7 @@ def kktix_reg_new_main(url, answer_index, registrationsNewApp_div, is_finish_che
if not is_finish_checkbox_click:
for retry_i in range(10):
# retry again.
is_need_refresh, is_finish_checkbox_click = kktix_check_agree_checkbox()
is_need_refresh, is_finish_checkbox_click = kktix_check_agree_checkbox(driver)
time.sleep(0.1)
if is_finish_checkbox_click:
break
@ -2075,7 +2132,7 @@ def kktix_reg_new_main(url, answer_index, registrationsNewApp_div, is_finish_che
# normal mode.
#print("# normal mode.")
if is_finish_checkbox_click:
kktix_press_next_button()
kktix_press_next_button(driver)
else:
print("unable to assign checkbox value")
else:
@ -2083,7 +2140,7 @@ def kktix_reg_new_main(url, answer_index, registrationsNewApp_div, is_finish_che
# 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:
kktix_press_next_button()
kktix_press_next_button(driver)
else:
print("unable to assign checkbox value")
else:
@ -2119,7 +2176,7 @@ def kktix_reg_new_main(url, answer_index, registrationsNewApp_div, is_finish_che
print("send ans:" + answer)
captcha_password_string = answer
if kktix_input_captcha_text(captcha_inner_div, captcha_password_string):
kktix_press_next_button()
kktix_press_next_button(driver)
else:
# exceed index, do nothing.
pass
@ -2130,7 +2187,7 @@ def kktix_reg_new_main(url, answer_index, registrationsNewApp_div, is_finish_che
return answer_index
def kktix_reg_new(url, answer_index, kktix_register_status_last):
def kktix_reg_new(driver, url, answer_index, kktix_register_status_last):
registerStatus = kktix_register_status_last
#---------------------------
@ -2164,11 +2221,11 @@ def kktix_reg_new(url, answer_index, kktix_register_status_last):
is_need_refresh = True
if not is_need_refresh:
is_need_refresh, is_finish_checkbox_click = kktix_check_agree_checkbox()
is_need_refresh, is_finish_checkbox_click = kktix_check_agree_checkbox(driver)
if not is_finish_checkbox_click:
# retry again.
is_need_refresh, is_finish_checkbox_click = kktix_check_agree_checkbox()
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.
@ -2215,7 +2272,7 @@ def kktix_reg_new(url, answer_index, kktix_register_status_last):
'''
except Exception as exc:
pass
print("find input fail:", exc)
#print("find input fail:", exc)
if is_need_refresh:
try:
@ -2229,7 +2286,10 @@ def kktix_reg_new(url, answer_index, kktix_register_status_last):
answer_index = -1
registerStatus = None
else:
answer_index = kktix_reg_new_main(url, answer_index, registrationsNewApp_div, is_finish_checkbox_click)
global auto_fill_ticket_number
global ticket_number
global kktix_area_keyword
answer_index = kktix_reg_new_main(url, answer_index, registrationsNewApp_div, is_finish_checkbox_click, auto_fill_ticket_number, ticket_number, kktix_area_keyword)
return answer_index, registerStatus
@ -2342,7 +2402,7 @@ def get_fami_target_area(date_keyword, area_keyword_1, area_keyword_2):
return areas
def fami_activity(url):
def fami_activity(driver, url):
#print("fami_activity bingo")
#---------------------------
@ -2356,13 +2416,23 @@ def fami_activity(url):
fami_start_to_buy_button.click()
time.sleep(0.5)
except Exception as exc:
print("click buyWaiting button fail")
print(exc)
pass
print("click buyWaiting button fail...")
#print(exc)
def fami_home(url):
def fami_home(driver, url):
print("fami_home bingo")
global is_assign_ticket_number
global ticket_number
global date_keyword
global area_keyword_1
global area_keyword_2
global area_auto_select_mode
is_select_box_visible = False
#---------------------------
@ -2467,7 +2537,7 @@ def fami_home(url):
pass
def urbtix_ticket_number_auto_select(url):
def urbtix_ticket_number_auto_select(driver, url, ticket_number):
ret = False
is_assign_ticket_number = False
@ -2516,7 +2586,7 @@ def urbtix_ticket_number_auto_select(url):
# True: area block appear.
# False: area block not appear.
# ps: return value for date auto select.
def urbtix_area_auto_select(url):
def urbtix_area_auto_select(driver, url, kktix_area_keyword):
ret = False
areas = None
@ -2601,7 +2671,7 @@ def urbtix_area_auto_select(url):
return ret
def urbtix_next_button_press(url):
def urbtix_next_button_press(driver, url):
ret = False
try:
el = driver.find_element(By.CSS_SELECTOR, '#express-purchase-btn > div > span')
@ -2618,20 +2688,24 @@ def urbtix_next_button_press(url):
return ret
def urbtix_performance(url):
def urbtix_performance(driver, url):
#print("urbtix performance bingo")
if auto_fill_ticket_number:
area_div_exist = False
if len(kktix_area_keyword) > 0:
area_div_exist = urbtix_area_auto_select(url)
global auto_fill_ticket_number
global ticket_number
ticket_number_select_exist, is_assign_ticket_number = urbtix_ticket_number_auto_select(url)
global kktix_area_keyword
global auto_press_next_step_button
if auto_fill_ticket_number:
area_div_exist = urbtix_area_auto_select(driver, url, kktix_area_keyword)
ticket_number_select_exist, is_assign_ticket_number = urbtix_ticket_number_auto_select(driver, url, ticket_number)
# todo.
if auto_press_next_step_button:
if is_assign_ticket_number:
urbtix_next_button_press(url)
urbtix_next_button_press(driver, url)
# purpose: area auto select
# return:
@ -2850,7 +2924,7 @@ def cityline_next_button_press(url):
return ret
def cityline_event(url):
def cityline_event(driver, url):
ret = False
is_non_member_displayed = False
@ -2925,11 +2999,16 @@ def cityline_captcha_auto_focus(url):
return ret
def cityline_performance(url):
def cityline_performance(driver, url):
#print("cityline bingo")
if "performance.do;" in url:
cityline_captcha_auto_focus(url)
global auto_fill_ticket_number
global kktix_area_keyword
global auto_press_next_step_button
global is_assign_ticket_number
if "?cid=" in url:
if auto_fill_ticket_number:
area_div_exist = False
@ -2951,7 +3030,7 @@ def cityline_performance(url):
break
def facebook_login(url):
def facebook_login(driver, url):
ret = False
try:
el = driver.find_element(By.CSS_SELECTOR, '#email')
@ -2971,6 +3050,9 @@ def facebook_login(url):
def main():
global driver
driver = load_config_from_local(driver)
# internal variable. 說明:這是一個內部變數,請略過。
url = ""
last_url = ""
@ -2981,6 +3063,7 @@ def main():
answer_index = -1
kktix_register_status_last = None
global debugMode
if debugMode:
print("Start to looping, detect browser url...")
@ -3110,7 +3193,7 @@ def main():
if len(str_exc)==0:
str_exc = repr(exc)
exit_bot_error_strings = [u'Max retries exceeded with url', u'chrome not reachable']
exit_bot_error_strings = [u'Max retries exceeded with url', u'chrome not reachable', u'without establishing a connection']
for str_chrome_not_reachable in exit_bot_error_strings:
# for python2
try:
@ -3177,7 +3260,7 @@ def main():
# for Max's test.
if '/Downloads/varify.html' in url:
tixcraft_verify(url)
tixcraft_verify(driver, url)
tixcraft_family = False
if 'tixcraft.com' in url:
@ -3187,6 +3270,7 @@ def main():
tixcraft_family = True
if tixcraft_family:
#print("tixcraft_family entry.")
if '/ticket/order' in url:
# do nothing.
continue
@ -3195,30 +3279,39 @@ def main():
# do nothing.
continue
tixcraft_redirect(url)
tixcraft_redirect(driver, url)
global date_auto_select_enable
global date_auto_select_mode
global date_keyword
if date_auto_select_enable:
date_auto_select(url)
date_auto_select(driver, url, date_auto_select_mode, date_keyword)
# choose area
if area_auto_select_enable:
area_auto_select(url)
global area_auto_select_enable
global area_keyword_1
global area_keyword_2
if area_auto_select_enable:
area_auto_select(driver, url, area_keyword_1, area_keyword_2)
if '/ticket/verify/' in url:
tixcraft_verify(url)
tixcraft_verify(driver, url)
# main app, to select ticket number.
if '/ticket/ticket/' in url:
is_verifyCode_editing = tixcraft_ticket_main(url, is_verifyCode_editing)
is_verifyCode_editing = tixcraft_ticket_main(driver, url, is_verifyCode_editing)
else:
# not is input verify code, reset flag.
is_verifyCode_editing = False
global auto_press_next_step_button
# for kktix.cc and kktix.com
if 'kktix.c' in url:
if '/registrations/new' in url:
answer_index, kktix_register_status_last = kktix_reg_new(url, answer_index, kktix_register_status_last)
answer_index, kktix_register_status_last = kktix_reg_new(driver, url, answer_index, kktix_register_status_last)
else:
is_event_page = False
if '/events/' in url:
@ -3229,7 +3322,7 @@ def main():
if auto_press_next_step_button:
# pass switch check.
#print("should press next here.")
kktix_events_press_next_button()
kktix_events_press_next_button(driver)
answer_index = -1
kktix_register_status_last = None
@ -3237,9 +3330,9 @@ def main():
# for famiticket
if 'famiticket.com' in url:
if '/Home/Activity/Info/' in url:
fami_activity(url)
fami_activity(driver, url)
if '/Sales/Home/Index/' in url:
fami_home(url)
fami_home(driver, url)
# for urbtix
@ -3260,11 +3353,11 @@ def main():
pass
if '/performanceDetail/' in url:
urbtix_performance(url)
urbtix_performance(driver, url)
if 'cityline.com' in url:
if '/event.do' in url:
cityline_event(url)
cityline_event(driver, url)
#pass
if '/Events.do' in url:
@ -3275,7 +3368,7 @@ def main():
pass
if '/performance.do' in url:
cityline_performance(url)
cityline_performance(driver, url)
if __name__ == "__main__":
main()

View File

@ -17,7 +17,7 @@ import sys
import platform
import json
CONST_APP_VERSION = u"MaxBot (2022.01.10)"
CONST_APP_VERSION = u"MaxBot (2022.01.12)"
CONST_FROM_TOP_TO_BOTTOM = u"from top to bottom"
CONST_FROM_BOTTOM_TO_TOP = u"from bottom to top"