-
-
Save Svision/04202d93fb32d14f00ac746879820722 to your computer and use it in GitHub Desktop.
import logging | |
import time | |
import json | |
import random | |
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 | |
from selenium.webdriver.common.by import By | |
from selenium.webdriver.chrome.service import Service | |
from webdriver_manager.chrome import ChromeDriverManager | |
USERNAME = '<username>' | |
PASSWORD = '<pwd>' | |
SCHEDULE = '<schedule number>' | |
COUNTRY_CODE = '<country code>' # en-ca for Canada-English | |
FACILITY_ID = '<facility id>' # 94 for Toronto (others please use F12 to check) | |
MY_SCHEDULE_DATE = "<your already scheduled date>" # 2022-05-16 WARNING: DON'T CHOOSE DATE LATER THAN ACTUAL SCHEDULED | |
MY_CONDITION = lambda month, day: True # MY_CONDITION = lambda month, day: int(month) == 11 and int(day) >= 5 | |
SLEEP_TIME = 60 # recheck time interval | |
DATE_URL = f"https://ais.usvisa-info.com/{COUNTRY_CODE}/niv/schedule/{SCHEDULE}/appointment/days/{FACILITY_ID}.json?appointments[expedite]=false" | |
TIME_URL = f"https://ais.usvisa-info.com/{COUNTRY_CODE}/niv/schedule/{SCHEDULE}/appointment/times/{FACILITY_ID}.json?date=%%s&appointments[expedite]=false" | |
APPOINTMENT_URL = f"https://ais.usvisa-info.com/{COUNTRY_CODE}/niv/schedule/{SCHEDULE}/appointment" | |
EXIT = False | |
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install())) | |
logging.basicConfig(level=logging.INFO, filename="visa.log", filemode="a+", format="%(asctime)-15s %(levelname)-8s %(message)s") | |
def login(): | |
# Bypass reCAPTCHA | |
driver.get(f"https://ais.usvisa-info.com/{COUNTRY_CODE}/niv") | |
time.sleep(1) | |
a = driver.find_element(By.XPATH, value='//a[@class="down-arrow bounce"]') | |
a.click() | |
time.sleep(1) | |
logging.info("start sign") | |
href = driver.find_element(By.XPATH, value='//*[@id="header"]/nav/div[2]/div[1]/ul/li[3]/a') | |
href.click() | |
time.sleep(1) | |
WebDriverWait(driver, 60).until(EC.presence_of_element_located((By.NAME, "commit"))) | |
logging.info("click bounce") | |
a = driver.find_element(By.XPATH, value='//a[@class="down-arrow bounce"]') | |
a.click() | |
time.sleep(1) | |
do_login_action() | |
def do_login_action(): | |
logging.info("input email") | |
user = driver.find_element(By.ID, value='user_email') | |
user.send_keys(USERNAME) | |
time.sleep(random.randint(1, 3)) | |
logging.info("input pwd") | |
pw = driver.find_element(By.ID, value='user_password') | |
pw.send_keys(PASSWORD) | |
time.sleep(random.randint(1, 3)) | |
logging.info("click privacy") | |
box = driver.find_element(By.CLASS_NAME, value='icheckbox') | |
box .click() | |
time.sleep(random.randint(1, 3)) | |
logging.info("commit") | |
btn = driver.find_element(By.NAME, value='commit') | |
btn.click() | |
time.sleep(random.randint(1, 3)) | |
try: | |
WebDriverWait(driver, 15).until(EC.presence_of_element_located((By.XPATH, "//a[contains(text(),'Continue')]"))) | |
logging.info("Login successfully!") | |
except TimeoutError: | |
logging.warning("Login failed!") | |
login() | |
def get_date(): | |
driver.get(DATE_URL) | |
if not is_logined(): | |
login() | |
return get_date() | |
else: | |
content = driver.find_element(By.TAG_NAME, value='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, value='pre').text | |
data = json.loads(content) | |
time = data.get("available_times")[-1] | |
logging.info("Get time successfully!") | |
return time | |
# BUGGY | |
def reschedule(date): | |
global EXIT | |
logging.info("Start Reschedule") | |
time = get_time(date) | |
driver.get(APPOINTMENT_URL) | |
data = { | |
"utf8": driver.find_element(By.NAME, value='utf8').get_attribute('value'), | |
"authenticity_token": driver.find_element(By.NAME, value='authenticity_token').get_attribute('value'), | |
"confirmed_limit_message": driver.find_element(By.NAME, value='confirmed_limit_message').get_attribute('value'), | |
"use_consulate_appointment_capacity": driver.find_element(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, | |
} | |
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): | |
logging.info("Successfully Rescheduled") | |
EXIT = True | |
else: | |
logging.warning("ReScheduled Fail") | |
logging.warning("POST REQUEST:\n") | |
logging.warning(headers) | |
logging.warning(data) | |
logging.warning("") | |
def is_logined(): | |
content = driver.page_source | |
if(content.find("error") != -1): | |
return False | |
return True | |
def print_date(dates): | |
for d in dates: | |
logging.info("%s \t business_day: %s" %(d.get('date'), d.get('business_day'))) | |
logging.info("\n") | |
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 | |
if __name__ == "__main__": | |
login() | |
retry_count = 0 | |
while 1: | |
if retry_count > 6: | |
break | |
try: | |
logging.info(datetime.today()) | |
logging.info("------------------") | |
dates = get_date()[:5] | |
print_date(dates) | |
date = get_available_date(dates) | |
if date: | |
reschedule(date) | |
if(EXIT): | |
break | |
time.sleep(SLEEP_TIME) | |
except: | |
retry_count += 1 | |
time.sleep(60*5) |
Any luck with the throttling? I've built a similar app on my side and getting the same issue, empty array after 48 requests. Then light ban for 5 hours
Do you know the period that 48 requests limit? Like 48 request within 1 hour?
I tried 5 locations every 10 minutes, also getting empty array after 4 hours. I'm not sure what the criteria is
Yes after getting the first empty array, I sleep for 1 hour until the next non-empty array (then it's back to checking every 5 minutes). But it still takes 5 hours to reset
I have a solution for that
Write to me in private visavisanot at gmail.com
Hello, I tested it with the Colombia country code, I had an error with the get_time method but I fixed, I have not yet been able to test the reschedule method, there aren't available days, but I have a question, Does this code contemplates the scheduling of the consular appointment and the appointment of the ASC? I
Hey dresansol, did you figure out how to reschedule the ASC appointment? I haven't been able to do so :(
Guys, has anyone found out a way to deal with the throttling/ban?
Hey dresansol, did you figure out how to reschedule the ASC appointment? I haven't been able to do so :(
Here there is a repo with ASC appointment: https://github.com/Narias1999/visabot
Also, there is a repo with the original gist, here: https://github.com/uxDaniel/visa_rescheduler
The appointment, ASC and consular, should be scheduled with the UI because the post request doesn’t work. You have to write a js code for click on each list box and set the dates
Yes after getting the first empty array, I sleep for 1 hour until the next non-empty array (then it's back to checking every 5 minutes). But it still takes 5 hours to reset
I have a solution for that Write to me in private visavisanot at gmail.com
I am also interested, emailed you.
I see that many people write here about the problem, so I will write here some points that will lead to a solution
In order to monitor the available dates, it is recommended to use accounts that have already had an interview meeting, even accounts that have already had an interview show available dates, if the account no longer shows available dates move to the next account, you need several accounts for this to monitor the dates,
The monitoring should be done in a separate window of the browser, and the central account for which you want to make an appointment in a separate window, if a queue is found, of course, continue the script in the window of the central account.
In addition, queues enter the system (except for very unusual cases) only during a round minute, for example 20:00 20:05 20:10 and so on... the mechanism that searches for available queues should only be activated during these minutes.
Someone needs to update the code here according to this data
Thanks for your code. It helps a lot.
Has anyone adjusted the code according to the data I wrote down?
Are you sure this was the reason? I've been executing my code for some friends and coincidentally they have been denied, but they have never told them anything related to the rescheduling process
Just wanted to come by and let you guys know that I had my visa cancelled last week by the US embassy, for running this script on my own, which apparently violates the Terms of use of the ais website.
Not sure how the heck they found out. I feel so miserable. Not worth it, mate. Good luck to y'all.
Was this canceled at the embassy before being approved or after it was approved some time after?
Hello Friends, I do not have any programming background. Could you please help me to run this script to get my appointment ?
its group of 3.
I am using a windows 11 laptop
hey guys, anyone has an idea about their rate limiting policy? I got 5 hour-bans twice and I dont want to risk it again. What is the optimal frequency and break-time to overcome this? Thanks in advance
ALGUIEN QUE TENGA EL UN ROBOT QUE FUNCIONE LE PAGARE SI VEO QUE FUNCIONA TOMANDO CITAS PARA LA EMBAJADA EN REPUBLICA DOMINICANA
SOMEONE WHO HAS A WORKING ROBOT, I WILL PAY YOU IF I SEE THAT IT WORKS TAKING APPOINTMENTS FOR THE EMBASSY IN THE DOMINICAN REPUBLIC
TRABAJO REPROGRAMANDO CITAS SI HAY ALGUN PROGRAMADOR BUENO LES PODRIA PAGAR SI VEO QUE FUNCIOAN TOMAR CITA CERCAS.
I WORK RESCHEDULING APPOINTMENTS IF THERE IS A GOOD PROGRAMMER I COULD PAY THEM IF I SEE THAT THEY WORK TO MAKE APPOINTMENTS NEARBY
TENGO BOT TRABAJANDO PERFECTO PARA REPUBLICA DOMINICANA, PERU, COLOMBIA Y MEXICO, CUALQUIER PREGUNTA A EL WHATSAPP +51 976581263
I do the same, I think is the only way for keep the checking stable.