Skip to content

Instantly share code, notes, and snippets.

@yaojialyu
Created November 5, 2020 09:24
Show Gist options
  • Save yaojialyu/0c59c23d84585cc6e889e394d928a164 to your computer and use it in GitHub Desktop.
Save yaojialyu/0c59c23d84585cc6e889e394d928a164 to your computer and use it in GitHub Desktop.
ais usvisa reschedule
# -*- coding: utf8 -*-
import time
import json
import random
import platform
from datetime import datetime
import requests
from selenium import webdriver
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 selenium.webdriver.common.desired_capabilities import DesiredCapabilities
USERNAME = '<username>'
PASSWORD = '<pwd>'
SCHEDULE = '<schedule number>'
PUSH_TOKEN = '<my push token>'
PUSH_USER = '<my push user>'
MY_SCHEDULE_DATE = "<current date>" # 2020-12-02
#MY_CONDITION = lambda month,day: int(month) == 11 or (int(month) == 12 and int(day) <=5)
MY_CONDITION = lambda month,day: int(month) == 11 and int(day) >= 5
SLEEP_TIME = 5 # recheck time interval
DATE_URL = "https://ais.usvisa-info.com/en-ec/niv/schedule/%s/appointment/days/108.json?appointments[expedite]=false" % SCHEDULE
TIME_URL = "https://ais.usvisa-info.com/en-ec/niv/schedule/%s/appointment/times/108.json?date=%%s&appointments[expedite]=false" % SCHEDULE
APPOINTMENT_URL = "https://ais.usvisa-info.com/en-ec/niv/schedule/%s/appointment" % SCHEDULE
HUB_ADDRESS = 'http://localhost:4444/wd/hub'
EXIT = False
def send(msg):
url = "https://api.pushover.net/1/messages.json"
data = {
"token": PUSH_TOKEN,
"user": PUSH_USER,
"message": msg
}
requests.post(url, data)
def get_drive():
local_use = platform.system() == 'Darwin'
if local_use:
dr = webdriver.Chrome(executable_path = './chromedriver')
else:
dr= webdriver.Remote(command_executor=HUB_ADDRESS, desired_capabilities=DesiredCapabilities.CHROME)
return dr
driver = get_drive()
def login():
# Bypass reCAPTCHA
driver.get("https://ais.usvisa-info.com/en-ec/niv")
time.sleep(1)
a = driver.find_element_by_xpath('//a[@class="down-arrow bounce"]')
a.click()
time.sleep(1)
print("start sign")
href = driver.find_element_by_xpath('//*[@id="header"]/nav/div[2]/div[1]/ul/li[3]/a')
href.click()
time.sleep(1)
Wait(driver, 60).until(EC.presence_of_element_located((By.NAME, "commit")))
print("click bounce")
a = driver.find_element_by_xpath('//a[@class="down-arrow bounce"]')
a.click()
time.sleep(1)
do_login_action()
def do_login_action():
print("input email")
user = driver.find_element_by_id('user_email')
user.send_keys(USERNAME)
time.sleep(random.randint(1, 3))
print("input pwd")
pw = driver.find_element_by_id('user_password')
pw.send_keys(PASSWORD)
time.sleep(random.randint(1, 3))
print("click privacy")
box = driver.find_element_by_class_name('icheckbox')
box .click()
time.sleep(random.randint(1, 3))
print("commit")
btn = driver.find_element_by_name('commit')
btn.click()
time.sleep(random.randint(1, 3))
Wait(driver, 60).until(EC.presence_of_element_located((By.XPATH, "//a[contains(text(),'Continue')]")))
print("Login successfully! ")
def get_date():
driver.get(DATE_URL)
if not is_logined():
login()
return get_date()
else:
content = driver.find_element_by_tag_name('pre').text
date = json.loads(content)
return date
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("Get time successfully!")
return time
def reschedule(date):
global EXIT
print("Start Reschedule")
time = get_time(date)
driver.get(APPOINTMENT_URL)
data = {
"utf8": driver.find_element_by_name('utf8').get_attribute('value'),
"authenticity_token": driver.find_element_by_name('authenticity_token').get_attribute('value'),
"confirmed_limit_message": driver.find_element_by_name('confirmed_limit_message').get_attribute('value'),
"use_consulate_appointment_capacity": driver.find_element_by_name('use_consulate_appointment_capacity').get_attribute('value'),
"appointments[consulate_appointment][facility_id]": "108",
"appointments[consulate_appointment][date]": date,
"appointments[consulate_appointment][time]": time,
}
headers = {
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.125 Safari/537.36",
"Referer": APPOINTMENT_URL,
"Cookie": "_yatri_session=" + driver.get_cookie("_yatri_session")["value"]
}
r = requests.post(APPOINTMENT_URL, headers=headers, data=data)
if(r.text.find('Successfully Scheduled') != -1):
print("Successfully Rescheduled")
send("Successfully Rescheduled")
EXIT = True
else:
print("ReScheduled Fail")
send("ReScheduled Fail")
def is_logined():
content = driver.page_source
if(content.find("error") != -1):
return False
return True
def print_date(dates):
for d in dates:
print("%s \t business_day: %s" %(d.get('date'), d.get('business_day')))
print()
last_seen = None
def get_available_date(dates):
global last_seen
def is_earlier(date):
return datetime.strptime(MY_SCHEDULE_DATE, "%Y-%m-%d") > datetime.strptime(date, "%Y-%m-%d")
for d in dates:
date = d.get('date')
if is_earlier(date) and date != last_seen:
_, month, day = date.split('-')
if(MY_CONDITION(month, day)):
last_seen = date
return date
def push_notification(dates):
msg = "date: "
for d in dates:
msg = msg + d.get('date') + '; '
send(msg)
if __name__ == "__main__":
login()
retry_count = 0
while 1:
if retry_count > 6:
break
try:
print(datetime.today())
print("------------------")
dates = get_date()[:5]
print_date(dates)
date = get_available_date(dates)
if date:
reschedule(date)
push_notification(dates)
if(EXIT):
break
time.sleep(SLEEP_TIME)
except:
retry_count += 1
time.sleep(60*5)
if(not EXIT):
send("HELP! Crashed.")
@yaojialyu
Copy link
Author

Hey guys, I wrote this script 16 months ago and I haven't tested it for a long time, things may be changed now. So that I cannot provide more insights/solutions for what you mentioned above. Please refer to others' replies. Good luck to you all.

One question, is there some place that refers to this script? since these days the replies become more than ever before.

@renoyin
Copy link

renoyin commented Mar 10, 2022

I just randomly came across this gist while searching ais on github lol.. Thanks for sharing :)

@Svision
Copy link

Svision commented Mar 16, 2022

The reschedule(date) method doesn't seem to work. Did anyone write a functional version? Appreciated it.
I modified the original script and included logging: https://gist.github.com/Svision/04202d93fb32d14f00ac746879820722

@israteneda
Copy link

israteneda commented Jun 30, 2022

@Svision I saw an implementation of @yaojialyu's gist here: https://github.com/uxDaniel/visa_rescheduler

@gustavodearmas
Copy link

Lo único malo es que el servidor lo bloquea a uno por entrar mucho :(
Yo Hice un boot también, busco la manera acceder a api importando request, logro solo iniciar sesión, de ahí no he pasado pasar. Alguna forma de guardar hacer request.Session() y que no se pierda el registro cuando le hago peticiones get a la página de appoiment?

@SZ-Edward
Copy link

Hi @yaojialyu , can you tell me what is number 108 for in the DATE_URL and TIME_URL please?

@groverjatin17
Copy link

Hi guys, I see that the APIs does not work if we call them from the codebase. Have the US Gov made changes in the server to not accept APIs?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment