Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exception occurred: Message: no such element: Unable to locate element #80

Open
turik97 opened this issue Mar 16, 2024 · 6 comments
Open

Comments

@turik97
Copy link

turik97 commented Mar 16, 2024

Available dates:
2026-07-30, 2026-07-31, 2026-08-04, 2026-08-06, 2026-08-07, 2026-08-10, 2026-08-11, 2026-08-12, 2026-08-13, 2026-08-14, 2026-08-17, 2026-08-18, 2026-08-20, 2026-08-21, 2026-08-24, 2026-08-25, 2026-08-26, 2026-08-27, 2026-08-28, 2026-08-31,
Got time successfully! 2026-07-30 08:45
Exception occurred: Message: no such element: Unable to locate element: {"method":"css selector","selector":"[name="utf8"]"}
(Session info: chrome=122.0.6261.112); For documentation on this error, please visit: https://www.selenium.dev/documentation/webdriver/troubleshooting/errors#no-such-element-exception
Stacktrace:
GetHandleVerifier [0x00007FF74E4FAD02+56930]
(No symbol) [0x00007FF74E46F602]
(No symbol) [0x00007FF74E3242E5]
(No symbol) [0x00007FF74E3698ED]
(No symbol) [0x00007FF74E369A2C]
(No symbol) [0x00007FF74E3AA967]
(No symbol) [0x00007FF74E38BCDF]
(No symbol) [0x00007FF74E3A81E2]
(No symbol) [0x00007FF74E38BA43]
(No symbol) [0x00007FF74E35D438]
(No symbol) [0x00007FF74E35E4D1]
GetHandleVerifier [0x00007FF74E876F8D+3711213]
GetHandleVerifier [0x00007FF74E8D04CD+4077101]
GetHandleVerifier [0x00007FF74E8C865F+4044735]
GetHandleVerifier [0x00007FF74E599736+706710]
(No symbol) [0x00007FF74E47B8DF]
(No symbol) [0x00007FF74E476AC4]
(No symbol) [0x00007FF74E476C1C]
(No symbol) [0x00007FF74E4668D4]
BaseThreadInitThunk [0x00007FFA0E52257D+29]
RtlUserThreadStart [0x00007FFA1040AA58+40]

@Des-cloud
Copy link

Delete the line "utf8" in data

@turik97
Copy link
Author

turik97 commented Mar 28, 2024

Ok people, since I had problems with this script since the beginning (First it was selenium issue for which I had to rewrite the driver location, then the config file was not getting parsed correctly, now the mentioned crash above which was solved by commenting the utf8 line as was advised) I want to post working as of 28/03/2024 version of visa.py which is running right now and was able to catch a slot within the specified range.
(please note that this script works without the config.ini and you need to include your data in the provided variables)

@turik97
Copy link
Author

turik97 commented Mar 28, 2024

`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')

Personal Info:

Account and current appointment info from https://ais.usvisa-info.com

USERNAME = '[email protected]'
PASSWORD = 'YOUR PASSWORD'

Find SCHEDULE_ID in re-schedule page link:

https://ais.usvisa-info.com/en-am/niv/schedule/{SCHEDULE_ID}/appointment

SCHEDULE_ID = '56637598'

Target Period:

PRIOD_START = '2024-03-26'
PRIOD_END = '2024-07-30'

Embassy Section:

YOUR_EMBASSY = 'en-ca-van'
EMBASSY = Embassies[YOUR_EMBASSY][0]
FACILITY_ID = Embassies[YOUR_EMBASSY][1]
REGEX_CONTINUE = Embassies[YOUR_EMBASSY][2]

RETRY_TIME_L_BOUND = 20
RETRY_TIME_U_BOUND = 30
WORK_LIMIT_TIME = 4
WORK_COOLDOWN_TIME = 0.5
BAN_COOLDOWN_TIME = 0.2

CHROMEDRIVER

LOCAL_USE = True
HUB_ADDRESS = 'http://localhost:9515/wd/hub'

Notification

PUSHOVER_TOKEN = ''
PUSHOVER_USER = ''
SENDGRID_API_KEY = ''
PERSONAL_SITE_USER = ''
PERSONAL_SITE_PASS = '
'
PUSH_TARGET_EMAIL = '[email protected]'
PERSONAL_PUSHER_URL = 'https://yoursite.com/api/esender.php'

Time Section:

minute = 60 # 60 seconds
hour = 60 * minute # 3600 seconds

Time between steps (interactions with forms)

STEP_TIME = 0.5

SIGN_IN_LINK = f"https://ais.usvisa-info.com/{EMBASSY}/niv/users/sign_in"
APPOINTMENT_URL = f"https://ais.usvisa-info.com/{EMBASSY}/niv/schedule/{SCHEDULE_ID}/appointment"
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"
SIGN_OUT_LINK = f"https://ais.usvisa-info.com/{EMBASSY}/niv/users/sign_out"

JS_SCRIPT = ("var req = new XMLHttpRequest();"
f"req.open('GET', '%s', false);"
"req.setRequestHeader('Accept', 'application/json, text/javascript, /; q=0.01');"
"req.setRequestHeader('X-Requested-With', 'XMLHttpRequest');"
f"req.setRequestHeader('Cookie', '_yatri_session=%s');"
"req.send(null);"
"return req.responseText;")

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="")
# 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 _:
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(SIGN_IN_LINK)
time.sleep(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, STEP_TIME)
auto_action("Password", "id", "user_password", "send", PASSWORD, STEP_TIME)
auto_action("Privacy", "class", "icheckbox", "click", "", STEP_TIME)
auto_action("Enter Panel", "name", "commit", "click", "", STEP_TIME)
Wait(driver, 60).until(EC.presence_of_element_located((By.XPATH, "//a[contains(text(), '" + REGEX_CONTINUE + "')]")))
print("\n\tlogin successful!\n")

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():
# Requesting to get the whole available dates
session = driver.get_cookie("_yatri_session")["value"]
script = JS_SCRIPT % (str(DATE_URL), session)
content = driver.execute_script(script)
return json.loads(content)

def get_time(date):
time_url = TIME_URL % date
session = driver.get_cookie("_yatri_session")["value"]
script = JS_SCRIPT % (str(time_url), session)
content = driver.execute_script(script)
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):
# Evaluation of different available 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):
# file_path: e.g. "log.txt"
with open(file_path, "a") as file:
file.write(str(datetime.now().time()) + ":\n" + log + "\n")

if LOCAL_USE:
options = webdriver.ChromeOptions()
options.add_experimental_option('excludeSwitches', ['enable-logging'])
driver = webdriver.Chrome(options=options)
else:
driver = webdriver.Remote(command_executor=HUB_ADDRESS, options=webdriver.ChromeOptions())

if name == "main":
first_loop = True
while 1:
LOG_FILE_NAME = "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:
# Ban Situation
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 as e:
# Log the exception and continue
error_msg = f"Exception occurred: {str(e)}\n"
print(error_msg)

print(msg)
info_logger(LOG_FILE_NAME, msg)
send_notification(END_MSG_TITLE, msg)
driver.get(SIGN_OUT_LINK)
driver.stop_client()
driver.quit()
`

@turik97 turik97 closed this as completed Mar 28, 2024
@turik97 turik97 reopened this Mar 28, 2024
@miguela1245
Copy link

línea utf8

Hi, could you help me by explaining what exactly you mean by the utf8 line?
Thanks

@nystateomind
Copy link

@turik97 could you please share your script as an attachment? I tried to use the code you pasted but formatting got messed up

@EpiphoneLP
Copy link

`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')

Personal Info:

Account and current appointment info from https://ais.usvisa-info.com

USERNAME = '[email protected]' PASSWORD = 'YOUR PASSWORD'

Find SCHEDULE_ID in re-schedule page link:

https://ais.usvisa-info.com/en-am/niv/schedule/{SCHEDULE_ID}/appointment

SCHEDULE_ID = '56637598'

Target Period:

PRIOD_START = '2024-03-26' PRIOD_END = '2024-07-30'

Embassy Section:

YOUR_EMBASSY = 'en-ca-van' EMBASSY = Embassies[YOUR_EMBASSY][0] FACILITY_ID = Embassies[YOUR_EMBASSY][1] REGEX_CONTINUE = Embassies[YOUR_EMBASSY][2]

RETRY_TIME_L_BOUND = 20 RETRY_TIME_U_BOUND = 30 WORK_LIMIT_TIME = 4 WORK_COOLDOWN_TIME = 0.5 BAN_COOLDOWN_TIME = 0.2

CHROMEDRIVER

LOCAL_USE = True HUB_ADDRESS = 'http://localhost:9515/wd/hub'

Notification

PUSHOVER_TOKEN = '' PUSHOVER_USER = '' SENDGRID_API_KEY = '' PERSONAL_SITE_USER = '' PERSONAL_SITE_PASS = '' PUSH_TARGET_EMAIL = '[email protected]' PERSONAL_PUSHER_URL = 'https://yoursite.com/api/esender.php'

Time Section:

minute = 60 # 60 seconds hour = 60 * minute # 3600 seconds

Time between steps (interactions with forms)

STEP_TIME = 0.5

SIGN_IN_LINK = f"https://ais.usvisa-info.com/{EMBASSY}/niv/users/sign_in" APPOINTMENT_URL = f"https://ais.usvisa-info.com/{EMBASSY}/niv/schedule/{SCHEDULE_ID}/appointment" 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" SIGN_OUT_LINK = f"https://ais.usvisa-info.com/{EMBASSY}/niv/users/sign_out"

JS_SCRIPT = ("var req = new XMLHttpRequest();" f"req.open('GET', '%s', false);" "req.setRequestHeader('Accept', 'application/json, text/javascript, /; q=0.01');" "req.setRequestHeader('X-Requested-With', 'XMLHttpRequest');" f"req.setRequestHeader('Cookie', '_yatri_session=%s');" "req.send(null);" "return req.responseText;")

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="") # 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 _: 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(SIGN_IN_LINK) time.sleep(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, STEP_TIME) auto_action("Password", "id", "user_password", "send", PASSWORD, STEP_TIME) auto_action("Privacy", "class", "icheckbox", "click", "", STEP_TIME) auto_action("Enter Panel", "name", "commit", "click", "", STEP_TIME) Wait(driver, 60).until(EC.presence_of_element_located((By.XPATH, "//a[contains(text(), '" + REGEX_CONTINUE + "')]"))) print("\n\tlogin successful!\n")

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(): # Requesting to get the whole available dates session = driver.get_cookie("_yatri_session")["value"] script = JS_SCRIPT % (str(DATE_URL), session) content = driver.execute_script(script) return json.loads(content)

def get_time(date): time_url = TIME_URL % date session = driver.get_cookie("_yatri_session")["value"] script = JS_SCRIPT % (str(time_url), session) content = driver.execute_script(script) 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): # Evaluation of different available 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): # file_path: e.g. "log.txt" with open(file_path, "a") as file: file.write(str(datetime.now().time()) + ":\n" + log + "\n")

if LOCAL_USE: options = webdriver.ChromeOptions() options.add_experimental_option('excludeSwitches', ['enable-logging']) driver = webdriver.Chrome(options=options) else: driver = webdriver.Remote(command_executor=HUB_ADDRESS, options=webdriver.ChromeOptions())

if name == "main": first_loop = True while 1: LOG_FILE_NAME = "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: # Ban Situation 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 as e: # Log the exception and continue error_msg = f"Exception occurred: {str(e)}\n" print(error_msg)

print(msg) info_logger(LOG_FILE_NAME, msg) send_notification(END_MSG_TITLE, msg) driver.get(SIGN_OUT_LINK) driver.stop_client() driver.quit() `

`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')

Personal Info:

Account and current appointment info from https://ais.usvisa-info.com

USERNAME = '[email protected]' PASSWORD = 'YOUR PASSWORD'

Find SCHEDULE_ID in re-schedule page link:

https://ais.usvisa-info.com/en-am/niv/schedule/{SCHEDULE_ID}/appointment

SCHEDULE_ID = '56637598'

Target Period:

PRIOD_START = '2024-03-26' PRIOD_END = '2024-07-30'

Embassy Section:

YOUR_EMBASSY = 'en-ca-van' EMBASSY = Embassies[YOUR_EMBASSY][0] FACILITY_ID = Embassies[YOUR_EMBASSY][1] REGEX_CONTINUE = Embassies[YOUR_EMBASSY][2]

RETRY_TIME_L_BOUND = 20 RETRY_TIME_U_BOUND = 30 WORK_LIMIT_TIME = 4 WORK_COOLDOWN_TIME = 0.5 BAN_COOLDOWN_TIME = 0.2

CHROMEDRIVER

LOCAL_USE = True HUB_ADDRESS = 'http://localhost:9515/wd/hub'

Notification

PUSHOVER_TOKEN = '' PUSHOVER_USER = '' SENDGRID_API_KEY = '' PERSONAL_SITE_USER = '' PERSONAL_SITE_PASS = '' PUSH_TARGET_EMAIL = '[email protected]' PERSONAL_PUSHER_URL = 'https://yoursite.com/api/esender.php'

Time Section:

minute = 60 # 60 seconds hour = 60 * minute # 3600 seconds

Time between steps (interactions with forms)

STEP_TIME = 0.5

SIGN_IN_LINK = f"https://ais.usvisa-info.com/{EMBASSY}/niv/users/sign_in" APPOINTMENT_URL = f"https://ais.usvisa-info.com/{EMBASSY}/niv/schedule/{SCHEDULE_ID}/appointment" 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" SIGN_OUT_LINK = f"https://ais.usvisa-info.com/{EMBASSY}/niv/users/sign_out"

JS_SCRIPT = ("var req = new XMLHttpRequest();" f"req.open('GET', '%s', false);" "req.setRequestHeader('Accept', 'application/json, text/javascript, /; q=0.01');" "req.setRequestHeader('X-Requested-With', 'XMLHttpRequest');" f"req.setRequestHeader('Cookie', '_yatri_session=%s');" "req.send(null);" "return req.responseText;")

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="") # 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 _: 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(SIGN_IN_LINK) time.sleep(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, STEP_TIME) auto_action("Password", "id", "user_password", "send", PASSWORD, STEP_TIME) auto_action("Privacy", "class", "icheckbox", "click", "", STEP_TIME) auto_action("Enter Panel", "name", "commit", "click", "", STEP_TIME) Wait(driver, 60).until(EC.presence_of_element_located((By.XPATH, "//a[contains(text(), '" + REGEX_CONTINUE + "')]"))) print("\n\tlogin successful!\n")

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(): # Requesting to get the whole available dates session = driver.get_cookie("_yatri_session")["value"] script = JS_SCRIPT % (str(DATE_URL), session) content = driver.execute_script(script) return json.loads(content)

def get_time(date): time_url = TIME_URL % date session = driver.get_cookie("_yatri_session")["value"] script = JS_SCRIPT % (str(time_url), session) content = driver.execute_script(script) 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): # Evaluation of different available 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): # file_path: e.g. "log.txt" with open(file_path, "a") as file: file.write(str(datetime.now().time()) + ":\n" + log + "\n")

if LOCAL_USE: options = webdriver.ChromeOptions() options.add_experimental_option('excludeSwitches', ['enable-logging']) driver = webdriver.Chrome(options=options) else: driver = webdriver.Remote(command_executor=HUB_ADDRESS, options=webdriver.ChromeOptions())

if name == "main": first_loop = True while 1: LOG_FILE_NAME = "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: # Ban Situation 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 as e: # Log the exception and continue error_msg = f"Exception occurred: {str(e)}\n" print(error_msg)

print(msg) info_logger(LOG_FILE_NAME, msg) send_notification(END_MSG_TITLE, msg) driver.get(SIGN_OUT_LINK) driver.stop_client() driver.quit() `

could you please share your script as an attachment? formatting got messed up

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants