Open etomak1228 opened 1 year ago
I modified the Line 103 to fix that element
href = driver.find_element(By.LINK_TEXT, 'Continue')
Thank you for your help @sirfanmkm but my line 103 is different. I am using the new file from pull request. Appreciate if you can assist me which one I need to change.
import time import json import random import requests import configparser from datetime import datetime
from selenium import webdriver from selenium.webdriver.chrome.service import Service from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.support.ui import WebDriverWait as Wait from selenium.webdriver.common.by import By from webdriver_manager.chrome import ChromeDriverManager
from sendgrid import SendGridAPIClient from sendgrid.helpers.mail import Mail
from embassy import *
config = configparser.ConfigParser() config.read('config.ini')
USERNAME = config['PERSONAL_INFO']['USERNAME'] PASSWORD = config['PERSONAL_INFO']['PASSWORD']
SCHEDULE_ID = config['PERSONAL_INFO']['SCHEDULE_ID']
PRIOD_START = config['PERSONAL_INFO']['PRIOD_START'] PRIOD_END = config['PERSONAL_INFO']['PRIOD_END']
YOUR_EMBASSY = config['PERSONAL_INFO']['YOUR_EMBASSY'] EMBASSY = Embassies[YOUR_EMBASSY][0] FACILITY_ID = Embassies[YOUR_EMBASSY][1] REGEX_CONTINUE = Embassies[YOUR_EMBASSY][2]
SENDGRID_API_KEY = config['NOTIFICATION']['SENDGRID_API_KEY']
PUSHOVER_TOKEN = config['NOTIFICATION']['PUSHOVER_TOKEN'] PUSHOVER_USER = config['NOTIFICATION']['PUSHOVER_USER']
PERSONAL_SITE_USER = config['NOTIFICATION']['PERSONAL_SITE_USER'] PERSONAL_SITE_PASS = config['NOTIFICATION']['PERSONAL_SITE_PASS'] PUSH_TARGET_EMAIL = config['NOTIFICATION']['PUSH_TARGET_EMAIL'] PERSONAL_PUSHER_URL = config['NOTIFICATION']['PERSONAL_PUSHER_URL']
minute = 60 hour = 60 * minute
STEP_TIME = 0.5
RETRY_TIME_L_BOUND = config['TIME'].getfloat('RETRY_TIME_L_BOUND') RETRY_TIME_U_BOUND = config['TIME'].getfloat('RETRY_TIME_U_BOUND')
WORK_LIMIT_TIME = config['TIME'].getfloat('WORK_LIMIT_TIME') WORK_COOLDOWN_TIME = config['TIME'].getfloat('WORK_COOLDOWN_TIME')
BAN_COOLDOWN_TIME = config['TIME'].getfloat('BAN_COOLDOWN_TIME')
LOCAL_USE = config['CHROMEDRIVER'].getboolean('LOCAL_USE')
HUB_ADDRESS = config['CHROMEDRIVER']['HUB_ADDRESS']
FIRST_PAGE_LINK = f"https://ais.usvisa-info.com/{EMBASSY}/niv" DATE_URL = f"https://ais.usvisa-info.com/{EMBASSY}/niv/schedule/{SCHEDULE_ID}/appointment/days/{FACILITY_ID}.json?appointments[expedite]=false" TIME_URL = f"https://ais.usvisa-info.com/{EMBASSY}/niv/schedule/{SCHEDULE_ID}/appointment/times/{FACILITY_ID}.json?date=%s&appointments[expedite]=false" APPOINTMENT_URL = f"https://ais.usvisa-info.com/{EMBASSY}/niv/schedule/{SCHEDULE_ID}/appointment" SIGN_OUT_LINK = f"https://ais.usvisa-info.com/{EMBASSY}/niv/users/sign_out"
def send_notification(title, msg): print(f"Sending notification!") if SENDGRID_API_KEY: message = Mail(from_email=USERNAME, to_emails=USERNAME, subject=msg, html_content=msg) try: sg = SendGridAPIClient(SENDGRID_API_KEY) response = sg.send(message) print(response.status_code) print(response.body) print(response.headers) except Exception as e: print(e.message) if PUSHOVER_TOKEN: url = "https://api.pushover.net/1/messages.json" data = { "token": PUSHOVER_TOKEN, "user": PUSHOVER_USER, "message": msg } requests.post(url, data) if PERSONAL_SITE_USER: url = PERSONAL_PUSHER_URL data = { "title": "VISA - " + str(title), "user": PERSONAL_SITE_USER, "pass": PERSONAL_SITE_PASS, "email": PUSH_TARGET_EMAIL, "msg": msg, } requests.post(url, data)
def auto_action(label, find_by, el_type, action, value, sleep_time=0): print("\t"+ label +":", end="")
match find_by.lower():
case 'id':
item = driver.find_element(By.ID, el_type)
case 'name':
item = driver.find_element(By.NAME, el_type)
case 'class':
item = driver.find_element(By.CLASS_NAME, el_type)
case 'xpath':
item = driver.find_element(By.XPATH, el_type)
case _:
return 0
# Do Action:
match action.lower():
case 'send':
item.send_keys(value)
case 'click':
item.click()
case _:
return 0
print("\t\tCheck!")
if sleep_time:
time.sleep(sleep_time)
def start_process():
driver.get(FIRST_PAGE_LINK)
time.sleep(STEP_TIME)
auto_action("Arrow down bounce", "xpath", '//a[@class="down-arrow bounce"]', "click", "", STEP_TIME)
auto_action("Login start", "xpath",'//*[@id="header"]/nav/div[2]/div[1]/ul/li[3]/a', "click", "", STEP_TIME)
Wait(driver, 60).until(EC.presence_of_element_located((By.NAME, "commit")))
auto_action("Click bounce", "xpath", '//a[@class="down-arrow bounce"]', "click", "", STEP_TIME)
auto_action("Email", "id", "user_email", "send", USERNAME, random.randint(1, 3))
auto_action("Password", "id", "user_password", "send", PASSWORD, random.randint(1, 3))
auto_action("Privacy", "class", "icheckbox", "click", "", random.randint(1, 3))
auto_action("Commit", "name", "commit", "click", "", random.randint(1, 3))
Wait(driver, 60).until(EC.presence_of_element_located((By.XPATH, "//a[contains(text(), '" + REGEX_CONTINUE + "')]")))
print("\n\tlogin successful!")
def reschedule(date): time = get_time(date) driver.get(APPOINTMENT_URL) headers = { "User-Agent": driver.execute_script("return navigator.userAgent;"), "Referer": APPOINTMENT_URL, "Cookie": "_yatri_session=" + driver.get_cookie("_yatri_session")["value"] } data = { "utf8": driver.find_element(by=By.NAME, value='utf8').get_attribute('value'), "authenticity_token": driver.find_element(by=By.NAME, value='authenticity_token').get_attribute('value'), "confirmed_limit_message": driver.find_element(by=By.NAME, value='confirmed_limit_message').get_attribute('value'), "use_consulate_appointment_capacity": driver.find_element(by=By.NAME, value='use_consulate_appointment_capacity').get_attribute('value'), "appointments[consulate_appointment][facility_id]": FACILITY_ID, "appointments[consulate_appointment][date]": date, "appointments[consulate_appointment][time]": time, } r = requests.post(APPOINTMENT_URL, headers=headers, data=data) if(r.text.find('Successfully Scheduled') != -1): title = "SUCCESS" msg = f"Rescheduled Successfully! {date} {time}" else: title = "FAIL" msg = f"Reschedule Failed!!! {date} {time}" return [title, msg]
def get_date():
driver.get(DATE_URL)
if not is_logged_in():
start_process()
return get_date()
else:
content = driver.find_element(By.TAG_NAME, 'pre').text
return json.loads(content)
def get_time(date): time_url = TIME_URL % date driver.get(time_url) content = driver.find_element(By.TAG_NAME, 'pre').text data = json.loads(content) time = data.get("available_times")[-1] print(f"Got time successfully! {date} {time}") return time
def is_logged_in(): content = driver.page_source if(content.find("error") != -1): return False return True
def get_available_date(dates):
def is_in_period(date, PSD, PED):
new_date = datetime.strptime(date, "%Y-%m-%d")
result = ( PED > new_date and new_date > PSD )
# print(f'{new_date.date()} : {result}', end=", ")
return result
PED = datetime.strptime(PRIOD_END, "%Y-%m-%d")
PSD = datetime.strptime(PRIOD_START, "%Y-%m-%d")
for d in dates:
date = d.get('date')
if is_in_period(date, PSD, PED):
return date
print(f"\n\nNo available dates between ({PSD.date()}) and ({PED.date()})!")
def info_logger(file_path, log):
with open(file_path, "a") as file:
file.write(str(datetime.now().time()) + ":\n" + log + "\n")
if LOCAL_USE: driver = webdriver.Chrome(service=Service(ChromeDriverManager().install())) else: driver = webdriver.Remote(command_executor=HUB_ADDRESS, options=webdriver.ChromeOptions())
if name == "main": first_loop = True while 1: LOG_FILENAME = "log" + str(datetime.now().date()) + ".txt" if first_loop: t0 = time.time() total_time = 0 Req_count = 0 start_process() first_loop = False Req_count += 1 try: msg = "-" * 60 + f"\nRequest count: {Req_count}, Log time: {datetime.today()}\n" print(msg) info_logger(LOG_FILE_NAME, msg) dates = get_date() if not dates:
msg = f"List is empty, Probabely banned!\n\tSleep for {BAN_COOLDOWN_TIME} hours!\n"
print(msg)
info_logger(LOG_FILE_NAME, msg)
send_notification("BAN", msg)
driver.get(SIGN_OUT_LINK)
time.sleep(BAN_COOLDOWN_TIME * hour)
first_loop = True
else:
# Print Available dates:
msg = ""
for d in dates:
msg = msg + "%s" % (d.get('date')) + ", "
msg = "Available dates:\n"+ msg
print(msg)
info_logger(LOG_FILE_NAME, msg)
date = get_available_date(dates)
if date:
# A good date to schedule for
END_MSG_TITLE, msg = reschedule(date)
break
RETRY_WAIT_TIME = random.randint(RETRY_TIME_L_BOUND, RETRY_TIME_U_BOUND)
t1 = time.time()
total_time = t1 - t0
msg = "\nWorking Time: ~ {:.2f} minutes".format(total_time/minute)
print(msg)
info_logger(LOG_FILE_NAME, msg)
if total_time > WORK_LIMIT_TIME * hour:
# Let program rest a little
send_notification("REST", f"Break-time after {WORK_LIMIT_TIME} hours | Repeated {Req_count} times")
driver.get(SIGN_OUT_LINK)
time.sleep(WORK_COOLDOWN_TIME * hour)
first_loop = True
else:
msg = "Retry Wait Time: "+ str(RETRY_WAIT_TIME)+ " seconds"
print(msg)
info_logger(LOG_FILE_NAME, msg)
time.sleep(RETRY_WAIT_TIME)
except:
# Exception Occured
msg = f"Break the loop after exception!\n"
END_MSG_TITLE = "EXCEPTION"
break
print(msg) info_logger(LOG_FILE_NAME, msg) send_notification(END_MSG_TITLE, msg) driver.get(SIGN_OUT_LINK) driver.stop_client() driver.quit()
Ok. This is how my visa.py file looks now with changes. I added new case for link_text
and updated auto_action
. Hope this helps.
def auto_action(label, find_by, el_type, action, value, sleep_time=0):
print("\t"+ label +":", end="")
# Find Element By
match find_by.lower():
case 'id':
item = driver.find_element(By.ID, el_type)
case 'name':
item = driver.find_element(By.NAME, el_type)
case 'class':
item = driver.find_element(By.CLASS_NAME, el_type)
case 'xpath':
item = driver.find_element(By.XPATH, el_type)
case 'link_text':
item = driver.find_element(By.LINK_TEXT, el_type)
case _:
return 0
# Do Action:
match action.lower():
case 'send':
item.send_keys(value)
case 'click':
item.click()
case _:
return 0
print("\t\tCheck!")
if sleep_time:
time.sleep(sleep_time)
def start_process():
# Bypass reCAPTCHA
driver.get(FIRST_PAGE_LINK)
time.sleep(STEP_TIME)
auto_action("Arrow down bounce", "xpath", '//a[@class="down-arrow bounce"]', "click", "", STEP_TIME)
# auto_action("Login start", "xpath", '//*[@id="header"]/nav/div[2]/div[1]/ul/li[3]/a', "click", "", STEP_TIME)
auto_action("Login start", "link_text", 'Continue', "click", "", STEP_TIME)
Thank so much. It is working now. Cheers bro!
It was working perfectly fine for months but suddenly stop working for the past 2 days. Program not able to continue in the log in page.