├── .gitignore ├── README.md └── nie.py /.gitignore: -------------------------------------------------------------------------------- 1 | *.log 2 | 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # get-nie-appointment 2 | A Python script that automates the process of getting an appointment for NIE assignation. It can be modified in order to change the type of appointment. 3 | 4 | ## Requirements 5 | 6 | * Python3 7 | * Selenium 8 | * Firefox installed 9 | * Gecko Driver 10 | 11 | ### Installing in Debian based distributions 12 | 13 | * Install pip3 and geckodriver 14 | ```sh 15 | sudo apt-get install pip3 firefox-geckodriver 16 | ``` 17 | 18 | * Install selenium 19 | ```sh 20 | pip3 install selenium 21 | ``` 22 | 23 | ### Installing in macOS 24 | 25 | * Get pip 26 | ```sh 27 | curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py 28 | ``` 29 | 30 | * Install pip 31 | ```sh 32 | python3 get-pip.py 33 | ``` 34 | 35 | * Install selenium 36 | ```sh 37 | pip3 install selenium 38 | ``` 39 | 40 | * Install 41 | ```sh 42 | brew install geckodriver 43 | ``` 44 | 45 | ## Running the script 46 | 47 | ```sh 48 | python3 nie.py 49 | ``` 50 | 51 | for example 52 | 53 | ```sh 54 | python3 nie.py Madrid AAE1111111 "Ezequiel Leonardo Aceto" ARGENTINA XXXX 64XXXXXXX my-persona-email@gmail.com "POLICIA-ASIGNACIÓN DE NIE" 55 | ``` 56 | 57 | ## Parameters 58 | 59 | For getting the requiered parameters, city and appointment type, visit: https://sede.administracionespublicas.gob.es/icpplustieb/index/ and complete the process one type manually. Then get the appointment type based on your city (which may vary from city to city). 60 | -------------------------------------------------------------------------------- /nie.py: -------------------------------------------------------------------------------- 1 | from selenium import webdriver 2 | from selenium.webdriver.support.ui import Select, WebDriverWait 3 | from selenium.webdriver.common.keys import Keys 4 | from selenium.webdriver.common.by import By 5 | from selenium.webdriver.support import expected_conditions as EC 6 | import sys 7 | 8 | driver = webdriver.Firefox() 9 | 10 | #scroll to bottom of page 11 | def wait(time): 12 | WebDriverWait(driver, time) 13 | def scroll(): 14 | driver.execute_script("window.scrollTo(0, document.body.scrollHeight);") 15 | 16 | #click button after scrolling to bottom of page 17 | def click_button(btnid): 18 | scroll() 19 | driver.find_element(By.ID, btnid).click() 20 | 21 | #select option from a drop down menu 22 | def select_option(menu_id, option): 23 | select = Select(driver.find_element(By.ID, menu_id)) 24 | select.select_by_visible_text(option) 25 | 26 | #fill a text field 27 | def fill_field(fld_id, text): 28 | field = driver.find_element(By.ID, fld_id) 29 | field.send_keys(text) 30 | 31 | #open the nie website 32 | def start(): 33 | driver.get("https://icp.administracionelectronica.gob.es/icpplustieb/index.html") 34 | 35 | #fill in and continue on the select city page 36 | def go_to_city_page(city): 37 | select_option("form", city) 38 | click_button("btnAceptar") 39 | 40 | #choose the correct type of appointment for NIE page 41 | def go_to_appointment_page(appointmentType): 42 | scroll() 43 | select_option("tramiteGrupo[1]", appointmentType) 44 | click_button("btnAceptar") 45 | #could make this better 46 | 47 | #conditions page after appointment page 48 | def go_to_conditions_page(): 49 | click_button("btnEntrar") 50 | 51 | #input basic info to ask for appointment 52 | def go_to_info_page(nie, name, country, expiry): 53 | click_button("rdbTipoDocPas") 54 | fill_field("txtIdCitado", passport) 55 | fill_field("txtDesCitado", name) 56 | click_button("btnEnviar") 57 | 58 | #ask for an appointment 59 | def require_appointment(): 60 | click_button("btnEnviar") 61 | 62 | #Select second office because it could return a single preselcted office or multiple where you have to make a choice 63 | def go_to_office_page(): 64 | try: 65 | driver.find_element(By.ID, "idSede").send_keys(Keys.DOWN) 66 | except: 67 | pass 68 | click_button("btnSiguiente") 69 | 70 | #if there are no offices to choose from, exit 71 | def no_appointment(): 72 | click_button("btnSalir") 73 | 74 | #info to be inputted after office selection - last step 75 | def add_info_compl(tel, email): 76 | fill_field("txtTelefonoCitado", tel) 77 | fill_field("emailUNO", email) 78 | fill_field("emailDOS", email) 79 | click_button("btnSiguiente") 80 | 81 | start() 82 | try: 83 | 84 | city = sys.argv[1] # as defined in the list of cities that the page has 85 | passport = sys.argv[2] 86 | name = sys.argv[3] 87 | country = sys.argv[4] # as defined in the list of countries that the page has ( in UPPERCASE ) 88 | birthyear = sys.argv[5] 89 | tel = sys.argv[6] # Spanish phone number without country code 90 | email = sys.argv[7] 91 | appointmentType = sys.argv[8] # as defined in the list of appointment types of the selected city 92 | 93 | print ("Looking for appointment of type: " + appointmentType) 94 | print ("\tCity of appointment: " + city) 95 | print ("\tName: " + name) 96 | print ("\tPassport: " + passport) 97 | print ("\tCountry: " + country) 98 | print ("\tYear of birth: " + birthyear) 99 | print ("\tEmail: " + email) 100 | print ("\tTelephone: " + tel) 101 | 102 | while True: 103 | go_to_city_page(city) 104 | go_to_appointment_page(appointmentType) 105 | go_to_conditions_page() 106 | go_to_info_page(passport, name, country, birthyear) 107 | require_appointment() 108 | try: 109 | go_to_office_page() 110 | add_info_compl(tel, email) 111 | if not driver.getPageSource().contains("No hay citas"): 112 | wait(1000) 113 | break 114 | else: 115 | click_button("btnSubmit") 116 | except: 117 | no_appointment() 118 | except KeyboardInterrupt: 119 | wait(100) 120 | 121 | #error page URL https://sede.administracionespublicas.gob.es/icpplustieb/acOfertarCita 122 | 123 | #office selection page URL is https://sede.administracionespublicas.gob.es/icpplustieb/acCitar 124 | 125 | #for the info_compl page URL is https://sede.administracionespublicas.gob.es/icpplustieb/acVerFormulario 126 | 127 | #could get generic back page: https://sede.administracionespublicas.gob.es/icpplustieb/infogenerica 128 | #use click_button("btnSubmit") if so 129 | --------------------------------------------------------------------------------