-
-
Save yaojialyu/0c59c23d84585cc6e889e394d928a164 to your computer and use it in GitHub Desktop.
# -*- 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.") |
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?
Hablame y lo checamos, yo busco lo mismo
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?
Hablame y lo checamos, yo busco lo mismo
Ya lo solucioné hace más de un año. Pero si lo que quieres es adelantar las citas, hasta hace mes y medio se podía, la Embajada ha cambiado todo.
Hey
Is there a way to contact you by email or anything? I await your response as soon as possible.
@yaojialyu
I want to work with you on a project similar to visa appointments , i want your email
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?