2023-01-11, tixcraft ocr verify code by ddddocr
parent
cf4707fc93
commit
b2ead02346
|
@ -20,6 +20,7 @@ from selenium.webdriver.support.ui import WebDriverWait
|
||||||
from selenium.webdriver.support import expected_conditions as EC
|
from selenium.webdriver.support import expected_conditions as EC
|
||||||
from selenium.webdriver.support.ui import Select
|
from selenium.webdriver.support.ui import Select
|
||||||
from selenium.webdriver.common.by import By
|
from selenium.webdriver.common.by import By
|
||||||
|
from selenium.webdriver.common.keys import Keys
|
||||||
# for selenium 4
|
# for selenium 4
|
||||||
from selenium.webdriver.chrome.service import Service
|
from selenium.webdriver.chrome.service import Service
|
||||||
from selenium.webdriver.common.action_chains import ActionChains
|
from selenium.webdriver.common.action_chains import ActionChains
|
||||||
|
@ -37,6 +38,10 @@ import warnings
|
||||||
from urllib3.exceptions import InsecureRequestWarning
|
from urllib3.exceptions import InsecureRequestWarning
|
||||||
warnings.simplefilter('ignore',InsecureRequestWarning)
|
warnings.simplefilter('ignore',InsecureRequestWarning)
|
||||||
|
|
||||||
|
# ocr
|
||||||
|
import base64
|
||||||
|
import ddddocr
|
||||||
|
|
||||||
import ssl
|
import ssl
|
||||||
ssl._create_default_https_context = ssl._create_unverified_context
|
ssl._create_default_https_context = ssl._create_unverified_context
|
||||||
|
|
||||||
|
@ -907,7 +912,6 @@ def tixcraft_redirect(driver, url):
|
||||||
game_name = ""
|
game_name = ""
|
||||||
|
|
||||||
# get game_name from url
|
# get game_name from url
|
||||||
if "/activity/detail/" in url:
|
|
||||||
url_split = url.split("/")
|
url_split = url.split("/")
|
||||||
if len(url_split) >= 6:
|
if len(url_split) >= 6:
|
||||||
game_name = url_split[5]
|
game_name = url_split[5]
|
||||||
|
@ -915,7 +919,6 @@ def tixcraft_redirect(driver, url):
|
||||||
if "/activity/detail/%s" % (game_name,) in url:
|
if "/activity/detail/%s" % (game_name,) in url:
|
||||||
# to support teamear
|
# to support teamear
|
||||||
entry_url = url.replace("/activity/detail/","/activity/game/")
|
entry_url = url.replace("/activity/detail/","/activity/game/")
|
||||||
#entry_url = "tixcraft.com/activity/game/%s" % (game_name,)
|
|
||||||
print("redirec to new url:", entry_url)
|
print("redirec to new url:", entry_url)
|
||||||
try:
|
try:
|
||||||
driver.get(entry_url)
|
driver.get(entry_url)
|
||||||
|
@ -927,7 +930,7 @@ def tixcraft_redirect(driver, url):
|
||||||
|
|
||||||
def tixcraft_date_auto_select(driver, url, config_dict):
|
def tixcraft_date_auto_select(driver, url, config_dict):
|
||||||
show_debug_message = True # debug.
|
show_debug_message = True # debug.
|
||||||
show_debug_message = False # online
|
#show_debug_message = False # online
|
||||||
|
|
||||||
# read config.
|
# read config.
|
||||||
date_auto_select_mode = config_dict["tixcraft"]["date_auto_select"]["mode"]
|
date_auto_select_mode = config_dict["tixcraft"]["date_auto_select"]["mode"]
|
||||||
|
@ -935,8 +938,6 @@ def tixcraft_date_auto_select(driver, url, config_dict):
|
||||||
pass_date_is_sold_out_enable = config_dict["tixcraft"]["pass_date_is_sold_out"]
|
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"]
|
auto_reload_coming_soon_page_enable = config_dict["tixcraft"]["auto_reload_coming_soon_page"]
|
||||||
|
|
||||||
is_date_selected = False
|
|
||||||
|
|
||||||
# PS: for big events, check sold out text maybe not helpful, due to database is too busy.
|
# PS: for big events, check sold out text maybe not helpful, due to database is too busy.
|
||||||
sold_out_text_list = ["選購一空","No tickets available","空席なし"]
|
sold_out_text_list = ["選購一空","No tickets available","空席なし"]
|
||||||
|
|
||||||
|
@ -962,15 +963,19 @@ def tixcraft_date_auto_select(driver, url, config_dict):
|
||||||
print("date keyword:", date_keyword)
|
print("date keyword:", date_keyword)
|
||||||
check_game_detail = True
|
check_game_detail = True
|
||||||
|
|
||||||
if check_game_detail:
|
|
||||||
date_list = None
|
date_list = None
|
||||||
|
if check_game_detail:
|
||||||
try:
|
try:
|
||||||
date_list = driver.find_elements(By.CSS_SELECTOR, '#gameList > table > tbody > tr')
|
date_list = driver.find_elements(By.CSS_SELECTOR, '#gameList > table > tbody > tr')
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
print("find #gameList fail")
|
print("find #gameList fail")
|
||||||
|
|
||||||
button_list = []
|
is_coming_soon = False
|
||||||
|
coming_soon_condictions_list = ['開賣','剩餘','天','小時','分鐘','秒','0',':','/']
|
||||||
|
|
||||||
|
button_list = None
|
||||||
if date_list is not None:
|
if date_list is not None:
|
||||||
|
button_list = []
|
||||||
for row in date_list:
|
for row in date_list:
|
||||||
# step 1: check keyword.
|
# step 1: check keyword.
|
||||||
is_match_keyword_row = False
|
is_match_keyword_row = False
|
||||||
|
@ -987,6 +992,15 @@ def tixcraft_date_auto_select(driver, url, config_dict):
|
||||||
row_text = ""
|
row_text = ""
|
||||||
|
|
||||||
if len(row_text) > 0:
|
if len(row_text) > 0:
|
||||||
|
is_match_all_coming_soon_condiction = True
|
||||||
|
for condiction_string in coming_soon_condictions_list:
|
||||||
|
if not condiction_string in row_text:
|
||||||
|
is_match_all_coming_soon_condiction = False
|
||||||
|
break
|
||||||
|
if is_match_all_coming_soon_condiction:
|
||||||
|
is_coming_soon = True
|
||||||
|
break
|
||||||
|
|
||||||
if len(date_keyword) == 0:
|
if len(date_keyword) == 0:
|
||||||
# no keyword, match all.
|
# no keyword, match all.
|
||||||
is_match_keyword_row = True
|
is_match_keyword_row = True
|
||||||
|
@ -1029,7 +1043,8 @@ def tixcraft_date_auto_select(driver, url, config_dict):
|
||||||
print("match date row, only need first row, start to break")
|
print("match date row, only need first row, start to break")
|
||||||
break
|
break
|
||||||
|
|
||||||
|
is_date_selected = False
|
||||||
|
if button_list is not None:
|
||||||
if len(button_list) > 0:
|
if len(button_list) > 0:
|
||||||
# default first row.
|
# default first row.
|
||||||
target_row_index = 0
|
target_row_index = 0
|
||||||
|
@ -1040,10 +1055,10 @@ def tixcraft_date_auto_select(driver, url, config_dict):
|
||||||
if date_auto_select_mode == CONST_RANDOM:
|
if date_auto_select_mode == CONST_RANDOM:
|
||||||
target_row_index = random.randint(0,len(button_list)-1)
|
target_row_index = random.randint(0,len(button_list)-1)
|
||||||
|
|
||||||
try:
|
|
||||||
if show_debug_message:
|
if show_debug_message:
|
||||||
print("clicking row number:", target_row_index)
|
print("clicking row number:", target_row_index)
|
||||||
|
|
||||||
|
try:
|
||||||
el = button_list[target_row_index]
|
el = button_list[target_row_index]
|
||||||
el.click()
|
el.click()
|
||||||
is_date_selected = True
|
is_date_selected = True
|
||||||
|
@ -1058,9 +1073,17 @@ def tixcraft_date_auto_select(driver, url, config_dict):
|
||||||
# (A)user input keywords, with matched text, but no hyperlink to click.
|
# (A)user input keywords, with matched text, but no hyperlink to click.
|
||||||
# (B)user input keywords, but not no matched text with hyperlink to click.
|
# (B)user input keywords, but not no matched text with hyperlink to click.
|
||||||
|
|
||||||
# [PS]: current reload condition only when No hyperlink button.
|
# [PS]: current reload condition only when
|
||||||
if auto_reload_coming_soon_page_enable and not is_date_selected:
|
if auto_reload_coming_soon_page_enable:
|
||||||
# auto refresh for date list page.
|
if is_coming_soon:
|
||||||
|
# case 2: match one row is coming soon.
|
||||||
|
try:
|
||||||
|
driver.refresh()
|
||||||
|
except Exception as exc:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
if not is_date_selected:
|
||||||
|
# case 1: No hyperlink button.
|
||||||
el_list = None
|
el_list = None
|
||||||
try:
|
try:
|
||||||
el_list = driver.find_elements(By.CSS_SELECTOR, '.btn-next')
|
el_list = driver.find_elements(By.CSS_SELECTOR, '.btn-next')
|
||||||
|
@ -1071,7 +1094,6 @@ def tixcraft_date_auto_select(driver, url, config_dict):
|
||||||
driver.refresh()
|
driver.refresh()
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
pass
|
pass
|
||||||
#print("find .btn-next fail:", exc)
|
|
||||||
|
|
||||||
return is_date_selected
|
return is_date_selected
|
||||||
|
|
||||||
|
@ -1576,9 +1598,81 @@ def tixcraft_verify(driver, presale_code):
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
def tixcraft_ticket_main(driver, config_dict):
|
def tixcraft_manully_keyin_verify_code(driver, ocr_answer = ""):
|
||||||
|
is_verifyCode_editing = False
|
||||||
|
|
||||||
|
# manually keyin verify code.
|
||||||
|
# start to input verify code.
|
||||||
|
form_verifyCode = None
|
||||||
|
try:
|
||||||
|
form_verifyCode = driver.find_element(By.ID, 'TicketForm_verifyCode')
|
||||||
|
except Exception as exc:
|
||||||
|
print("find form_verifyCode fail")
|
||||||
|
|
||||||
|
if form_verifyCode is not None:
|
||||||
|
is_visible = False
|
||||||
|
try:
|
||||||
|
if form_verifyCode.is_enabled():
|
||||||
|
is_visible = True
|
||||||
|
except Exception as exc:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if is_visible:
|
||||||
|
try:
|
||||||
|
form_verifyCode.click()
|
||||||
|
if len(ocr_answer)==4:
|
||||||
|
#print("start to auto submit.")
|
||||||
|
form_verifyCode.send_keys(ocr_answer)
|
||||||
|
form_verifyCode.send_keys(Keys.ENTER)
|
||||||
|
is_verifyCode_editing = True
|
||||||
|
except Exception as exc:
|
||||||
|
print("click form_verifyCode fail, tring to use javascript.")
|
||||||
|
# plan B
|
||||||
|
try:
|
||||||
|
driver.execute_script("document.getElementById(\"TicketForm_verifyCode\").focus();")
|
||||||
|
is_verifyCode_editing = True
|
||||||
|
except Exception as exc:
|
||||||
|
print("click form_verifyCode fail")
|
||||||
|
pass
|
||||||
|
pass
|
||||||
|
return is_verifyCode_editing
|
||||||
|
|
||||||
|
#PS: credit to LinShihJhang's share
|
||||||
|
def tixcraft_auto_ocr(driver, ocr):
|
||||||
|
print("start to ddddocr")
|
||||||
|
try:
|
||||||
|
row_text = select_obj.first_selected_option.text
|
||||||
|
except Exception as exc:
|
||||||
|
pass
|
||||||
|
|
||||||
|
form_verifyCode_base64 = driver.execute_async_script("""
|
||||||
|
var canvas = document.createElement('canvas');
|
||||||
|
var context = canvas.getContext('2d');
|
||||||
|
var img = document.getElementById('yw0');
|
||||||
|
canvas.height = img.naturalHeight;
|
||||||
|
canvas.width = img.naturalWidth;
|
||||||
|
context.drawImage(img, 0, 0);
|
||||||
|
|
||||||
|
callback = arguments[arguments.length - 1];
|
||||||
|
callback(canvas.toDataURL());
|
||||||
|
""")
|
||||||
|
img_base64 = base64.b64decode(form_verifyCode_base64.split(',')[1])
|
||||||
|
orc_answer = ocr.classification(img_base64)
|
||||||
|
if not orc_answer is None:
|
||||||
|
print("orc_answer:", orc_answer)
|
||||||
|
if len(orc_answer)==4:
|
||||||
|
tixcraft_manully_keyin_verify_code(driver, orc_answer)
|
||||||
|
else:
|
||||||
|
tixcraft_manully_keyin_verify_code(driver, "")
|
||||||
|
|
||||||
|
def tixcraft_ticket_main(driver, config_dict, ocr):
|
||||||
is_finish_checkbox_click = False
|
is_finish_checkbox_click = False
|
||||||
auto_check_agree = config_dict["auto_check_agree"]
|
auto_check_agree = config_dict["auto_check_agree"]
|
||||||
|
|
||||||
|
#auto_verify_code = config_dict["auto_verify_code"]
|
||||||
|
auto_verify_code = False
|
||||||
|
auto_verify_code = True
|
||||||
|
|
||||||
if auto_check_agree:
|
if auto_check_agree:
|
||||||
tixcraft_ticket_agree(driver)
|
tixcraft_ticket_agree(driver)
|
||||||
|
|
||||||
|
@ -1606,7 +1700,6 @@ def tixcraft_ticket_main(driver, config_dict):
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
is_verifyCode_editing = False
|
|
||||||
is_ticket_number_assigned = False
|
is_ticket_number_assigned = False
|
||||||
if not select_obj is None:
|
if not select_obj is None:
|
||||||
row_text = None
|
row_text = None
|
||||||
|
@ -1620,6 +1713,8 @@ def tixcraft_ticket_main(driver, config_dict):
|
||||||
# ticket assign.
|
# ticket assign.
|
||||||
is_ticket_number_assigned = True
|
is_ticket_number_assigned = True
|
||||||
|
|
||||||
|
is_verifyCode_editing = False
|
||||||
|
|
||||||
# must wait select object ready to assign ticket number.
|
# must wait select object ready to assign ticket number.
|
||||||
if not is_ticket_number_assigned:
|
if not is_ticket_number_assigned:
|
||||||
# only this case:"ticket number changed by bot" to play sound!
|
# only this case:"ticket number changed by bot" to play sound!
|
||||||
|
@ -1631,36 +1726,11 @@ def tixcraft_ticket_main(driver, config_dict):
|
||||||
|
|
||||||
# must wait ticket number assign to focus captcha.
|
# must wait ticket number assign to focus captcha.
|
||||||
if is_ticket_number_assigned:
|
if is_ticket_number_assigned:
|
||||||
# only this case to focus()
|
if not auto_verify_code:
|
||||||
# start to input verify code.
|
is_verifyCode_editing = tixcraft_manully_keyin_verify_code(driver)
|
||||||
form_verifyCode = None
|
else:
|
||||||
try:
|
tixcraft_auto_ocr(driver, ocr)
|
||||||
form_verifyCode = driver.find_element(By.ID, 'TicketForm_verifyCode')
|
|
||||||
except Exception as exc:
|
|
||||||
print("find form_verifyCode fail")
|
|
||||||
|
|
||||||
if form_verifyCode is not None:
|
|
||||||
is_visible = False
|
|
||||||
try:
|
|
||||||
if form_verifyCode.is_enabled():
|
|
||||||
is_visible = True
|
|
||||||
except Exception as exc:
|
|
||||||
pass
|
|
||||||
|
|
||||||
if is_visible:
|
|
||||||
try:
|
|
||||||
form_verifyCode.click()
|
|
||||||
is_verifyCode_editing = True
|
is_verifyCode_editing = True
|
||||||
except Exception as exc:
|
|
||||||
print("click form_verifyCode fail, tring to use javascript.")
|
|
||||||
# plan B
|
|
||||||
try:
|
|
||||||
driver.execute_script("document.getElementById(\"TicketForm_verifyCode\").focus();")
|
|
||||||
is_verifyCode_editing = True
|
|
||||||
except Exception as exc:
|
|
||||||
print("click form_verifyCode fail")
|
|
||||||
pass
|
|
||||||
pass
|
|
||||||
|
|
||||||
print("is_finish_checkbox_click:", is_finish_checkbox_click)
|
print("is_finish_checkbox_click:", is_finish_checkbox_click)
|
||||||
|
|
||||||
|
@ -4804,21 +4874,24 @@ def list_all_cookies(driver):
|
||||||
cookies_dict[cookie['name']] = cookie['value']
|
cookies_dict[cookie['name']] = cookie['value']
|
||||||
print(cookies_dict)
|
print(cookies_dict)
|
||||||
|
|
||||||
def tixcraft_main(driver, url, config_dict, is_verifyCode_editing):
|
def tixcraft_main(driver, url, config_dict, is_verifyCode_editing, ocr):
|
||||||
if url == 'https://tixcraft.com/':
|
if url == 'https://tixcraft.com/':
|
||||||
tixcraft_home(driver)
|
tixcraft_home(driver)
|
||||||
|
|
||||||
if url == 'https://indievox.com/':
|
if url == 'https://indievox.com/':
|
||||||
tixcraft_home(driver)
|
tixcraft_home(driver)
|
||||||
|
|
||||||
|
if "/activity/detail/" in url:
|
||||||
is_redirected = tixcraft_redirect(driver, url)
|
is_redirected = tixcraft_redirect(driver, url)
|
||||||
|
|
||||||
is_date_selected = False
|
is_date_selected = False
|
||||||
|
if "/activity/game/" in url:
|
||||||
date_auto_select_enable = config_dict["tixcraft"]["date_auto_select"]["enable"]
|
date_auto_select_enable = config_dict["tixcraft"]["date_auto_select"]["enable"]
|
||||||
if date_auto_select_enable:
|
if date_auto_select_enable:
|
||||||
is_date_selected = tixcraft_date_auto_select(driver, url, config_dict)
|
is_date_selected = tixcraft_date_auto_select(driver, url, config_dict)
|
||||||
|
|
||||||
# choose area
|
# choose area
|
||||||
|
if '/ticket/area/' in url:
|
||||||
area_auto_select_enable = config_dict["tixcraft"]["area_auto_select"]["enable"]
|
area_auto_select_enable = config_dict["tixcraft"]["area_auto_select"]["enable"]
|
||||||
if area_auto_select_enable:
|
if area_auto_select_enable:
|
||||||
tixcraft_area_auto_select(driver, url, config_dict)
|
tixcraft_area_auto_select(driver, url, config_dict)
|
||||||
|
@ -4830,7 +4903,7 @@ def tixcraft_main(driver, url, config_dict, is_verifyCode_editing):
|
||||||
# main app, to select ticket number.
|
# main app, to select ticket number.
|
||||||
if '/ticket/ticket/' in url:
|
if '/ticket/ticket/' in url:
|
||||||
if not is_verifyCode_editing:
|
if not is_verifyCode_editing:
|
||||||
is_verifyCode_editing = tixcraft_ticket_main(driver, config_dict)
|
is_verifyCode_editing = tixcraft_ticket_main(driver, config_dict, ocr)
|
||||||
else:
|
else:
|
||||||
is_verifyCode_editing = False
|
is_verifyCode_editing = False
|
||||||
|
|
||||||
|
@ -4884,7 +4957,7 @@ def famiticket_main(driver, url, config_dict):
|
||||||
|
|
||||||
def urbtix_main(driver, url, config_dict):
|
def urbtix_main(driver, url, config_dict):
|
||||||
# http://msg.urbtix.hk
|
# http://msg.urbtix.hk
|
||||||
waiting_for_access_url = ['/session/landing-timer/0/?type=busy','msg.urbtix.hk','busy.urbtix.hk']
|
waiting_for_access_url = ['/session/landing-timer/','msg.urbtix.hk','busy.urbtix.hk']
|
||||||
for waiting_url in waiting_for_access_url:
|
for waiting_url in waiting_for_access_url:
|
||||||
if waiting_url in url:
|
if waiting_url in url:
|
||||||
# delay to avoid ip block.
|
# delay to avoid ip block.
|
||||||
|
@ -5050,6 +5123,8 @@ def main():
|
||||||
if debugMode:
|
if debugMode:
|
||||||
print("Start to looping, detect browser url...")
|
print("Start to looping, detect browser url...")
|
||||||
|
|
||||||
|
ocr = ddddocr.DdddOcr()
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
time.sleep(0.1)
|
time.sleep(0.1)
|
||||||
|
|
||||||
|
@ -5177,7 +5252,7 @@ def main():
|
||||||
tixcraft_family = True
|
tixcraft_family = True
|
||||||
|
|
||||||
if tixcraft_family:
|
if tixcraft_family:
|
||||||
is_verifyCode_editing = tixcraft_main(driver, url, config_dict, is_verifyCode_editing)
|
is_verifyCode_editing = tixcraft_main(driver, url, config_dict, is_verifyCode_editing, ocr)
|
||||||
|
|
||||||
# for kktix.cc and kktix.com
|
# for kktix.cc and kktix.com
|
||||||
if 'kktix.c' in url:
|
if 'kktix.c' in url:
|
||||||
|
@ -5210,6 +5285,7 @@ if __name__ == "__main__":
|
||||||
CONST_MODE_CLI = 1
|
CONST_MODE_CLI = 1
|
||||||
mode = CONST_MODE_GUI
|
mode = CONST_MODE_GUI
|
||||||
#mode = CONST_MODE_CLI
|
#mode = CONST_MODE_CLI
|
||||||
|
|
||||||
if mode == CONST_MODE_GUI:
|
if mode == CONST_MODE_GUI:
|
||||||
main()
|
main()
|
||||||
else:
|
else:
|
||||||
|
@ -5218,7 +5294,14 @@ if __name__ == "__main__":
|
||||||
#captcha_text_div_text = u"請在下方空白處輸入引號內文字:「abc」"
|
#captcha_text_div_text = u"請在下方空白處輸入引號內文字:「abc」"
|
||||||
#captcha_text_div_text = u"請在下方空白處輸入引號內文字:「0118eveconcert」(請以半形小寫作答。)"
|
#captcha_text_div_text = u"請在下方空白處輸入引號內文字:「0118eveconcert」(請以半形小寫作答。)"
|
||||||
#captcha_text_div_text = "在《DEEP AWAKENING見過深淵的人》專輯中,哪一首為合唱曲目? 【V6】深淵 、【Z5】浮木、【J8】無聲、【C1】以上皆非 (請以半形輸入法作答,大小寫/阿拉伯數字需要一模一樣,範例:A2)"
|
#captcha_text_div_text = "在《DEEP AWAKENING見過深淵的人》專輯中,哪一首為合唱曲目? 【V6】深淵 、【Z5】浮木、【J8】無聲、【C1】以上皆非 (請以半形輸入法作答,大小寫/阿拉伯數字需要一模一樣,範例:A2)"
|
||||||
#captcha_text_div_text = "Super Junior 的隊長是以下哪位? 【v】神童 【w】藝聲 【x】利特 【y】始源 若你覺得答案為 a,請輸入 a (英文為半形小寫)"
|
captcha_text_div_text = "Super Junior 的隊長是以下哪位? 【v】神童 【w】藝聲 【x】利特 【y】始源 若你覺得答案為 a,請輸入 a (英文為半形小寫)"
|
||||||
inferred_answer_string, answer_list = get_answer_list_from_question_string(None, captcha_text_div_text)
|
inferred_answer_string, answer_list = get_answer_list_from_question_string(None, captcha_text_div_text)
|
||||||
print("inferred_answer_string:", inferred_answer_string)
|
print("inferred_answer_string:", inferred_answer_string)
|
||||||
print("answer_list:", answer_list)
|
print("answer_list:", answer_list)
|
||||||
|
|
||||||
|
ocr = ddddocr.DdddOcr()
|
||||||
|
with open('captcha-oapi.png', 'rb') as f:
|
||||||
|
image_bytes = f.read()
|
||||||
|
res = ocr.classification(image_bytes)
|
||||||
|
print(res)
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,12 @@ certifi
|
||||||
chardet
|
chardet
|
||||||
cryptography
|
cryptography
|
||||||
idna
|
idna
|
||||||
selenium
|
selenium>=4.0.0
|
||||||
selenium-stealth
|
selenium-stealth
|
||||||
undetected-chromedriver
|
undetected-chromedriver
|
||||||
playsound
|
playsound
|
||||||
pyperclip
|
pyperclip
|
||||||
|
ddddocr
|
||||||
|
urllib3>=1.21.1
|
||||||
|
numpy==1.21
|
||||||
|
daal==2021.4.0
|
|
@ -19,7 +19,7 @@ import json
|
||||||
import webbrowser
|
import webbrowser
|
||||||
import pyperclip
|
import pyperclip
|
||||||
|
|
||||||
CONST_APP_VERSION = u"MaxBot (2023.01.10)"
|
CONST_APP_VERSION = u"MaxBot (2023.01.11)"
|
||||||
|
|
||||||
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