Ho scritto un codice per generare cookie (_forum_session e _t) tramite Selenium e Python. Ma in questo caso dobbiamo anche inserire manualmente il numero di telefono e l’OPT per la convalida. Voglio generare i cookie in modo completamente automatico tramite codice, non voglio inserire manualmente nulla. Come posso raggiungere questo obiettivo?
Puoi fare un passo indietro e descrivere quale problema risolveranno quei cookie?
Cosa stai cercando di realizzare? Stai cercando di autenticare Discourse contro la tua app? Forse dai un’occhiata a DiscourseConnect - Single Sign-On Ufficiale per Discourse (sso)?
Tramite generate_cookies.py, ho ricevuto cookies.pkl che uso per testare automaticamente il login ogni 5 minuti.
Quindi ho un file login_12.py che chiamo ogni 5 minuti per testare i miei login
login_12.py (di seguito un esempio di codice)
import cookies.pkl
driver.get("https://forum.discourse.org/")
WebDriverWait(driver, 20).until(EC.presence_of_element_located((By.XPATH, '/html/body')))
logger.debug(jlog.format(timestamp=datetime.now(), level="DEBUG", status="Executing", message="Homepage reloaded"))
time.sleep(3)
cookies = pickle.load(open("cookies.pkl", "rb"))
for cookie in cookies:
print(cookie)
driver.add_cookie(cookie)
logger.debug(jlog.format(timestamp=datetime.now(), level="DEBUG", status="Executing", message="Added cookies"))
time.sleep(2)
driver.get(driver.current_url)
logger.debug(jlog.format(timestamp=datetime.now(), level="DEBUG", status="Executing", message="Homepage reloaded"))
Voglio generare i cookie automaticamente senza usare il browser, in modo che l’intero processo sia automatico.
Stai ancora descrivendo la tua soluzione proposta invece del problema che stai cercando di risolvere.
Perché hai bisogno dei cookie se non hai bisogno di un browser?
Stai cercando di far sì che la tua app esterna possa fare qualcosa a Discourse? Forse basta usare una chiave API?
Perché hai bisogno dei cookie?
Risposta: perché senza aggiungere il file cookies.pkl non siamo in grado di accedere tramite il file login_12.py.
Al momento, per generare i cookie, dobbiamo inserire manualmente il numero di telefono e l’OTP nel browser Chrome Driver. Non voglio inserire nulla manualmente, ecco perché non voglio usare il browser per generare i cookie.
generate_cookies.py (codice di esempio)
from selenium import webdriver
import undetected_chromedriver as uc
options = uc.ChromeOptions()
#options.add_argument('--headless')
options.add_argument("--disable-extensions")
options.add_argument("--disable-popup-blocking")
# login
GMAIL = 'discourse.mytest@ymail.com'
PASSWORD = 'test1234'
driver.get("https://forun.discourse.org/")
print(driver.title)
WebDriverWait(driver, 20).until(EC.presence_of_element_located((By.XPATH, '/html/body')))
print('Homepage caricata')
WebDriverWait(driver, 20).until(EC.presence_of_element_located((By.CLASS_NAME, 'login-button')))
login = driver.find_elements_by_class_name("login-button")[0]
print(login)
login.send_keys(Keys.RETURN)
print(driver.current_url)
driver.get(driver.current_url)
print("email")
WebDriverWait(driver, 20).until(EC.presence_of_element_located((By.XPATH, '/html/body')))
print('Pagina email caricata')
#print(driver.page_source)
driver.find_element_by_xpath("/html/body/div[1]/div[1]/div[2]/div/div[2]/div/div/div[2]/div/div[1]/div/form/span/section/div/div/div[1]/div/div[1]/div/div[1]/input").send_keys(GMAIL)
driver.find_element_by_xpath("/html/body/div[1]/div[1]/div[2]/div/div[2]/div/div/div[2]/div/div[1]/div/form/span/section/div/div/div[1]/div/div[1]/div/div[1]/input").send_keys(Keys.RETURN)
print("Email inserita")
time.sleep(3)
WebDriverWait(driver, 20).until(EC.presence_of_element_located((By.XPATH, '/html/body')))
print('Pagina password caricata')
#print(driver.page_source)
driver.find_element_by_xpath("/html/body/div[1]/div[1]/div[2]/div/div[2]/div/div/div[2]/div/div[1]/div/form/span/section/div/div/div[1]/div[1]/div/div/div/div/div[1]/div/div[1]/input").send_keys(PASSWORD)
driver.find_element_by_xpath("/html/body/div[1]/div[1]/div[2]/div/div[2]/div/div/div[2]/div/div[1]/div/form/span/section/div/div/div[1]/div[1]/div/div/div/div/div[1]/div/div[1]/input").send_keys(Keys.RETURN)
print("Password inserita")
time.sleep(3)
WebDriverWait(driver, 20).until(EC.presence_of_element_located((By.XPATH, '/html/body')))
print('Login completato')
print(driver.title)
#print(driver.find_element_by_xpath("/html/body").get_attribute('innerHTML'))
if not "Discourse Forum" in driver.title:
raise Exception('Errore di login')
else:
print("Homepage caricata")
driver.get(driver.current_url+'/c/announcements/5')
WebDriverWait(driver, 20).until(EC.presence_of_element_located((By.XPATH, '/html/head/title')))
print('Tentativo pagina annunci')
print(driver.title)
Infine, voglio ottenere questo.
if (ottieni scadenza dal local-storage del browser headless >= ora)
{
#esegui genera cookie (problema con questa parte per renderla automatica, attualmente alcune parti sono manuali)
#carica il file cookies.pkl nella directory appropriata
}else{
#esegui login_12.py per accedere
}
#accedi al local-storage per il browser headless chrome
#aggiungi/aggiorna la data di scadenza nella variabile local-storage
Come e perché?
Puoi inserire automaticamente il numero di telefono (dove viene richiesto?) e disattivare l’OTP per quell’utente?
@RGJ Esistono endpoint o API disponibili che possiamo chiamare per ottenere un token di accesso di accesso valido?
Se quello che stai cercando di fare è permettere alle persone di accedere a Discourse usando la tua altra app, o di accedere alla tua altra app usando Discourse, allora vuoi implementare DiscourseConnect, a cui ho linkato sopra. Puoi consultare quella pagina per la documentazione e gli esempi di codice.
Non mi è ancora chiaro cosa stai cercando di ottenere.
Se devi integrare un’altra pagina web utilizzando l’autenticazione di Discourse come fonte di verità, puoi utilizzare Discourse come provider SSO.
Se devi effettuare chiamate server-to-server all’API di Discourse, puoi creare chiavi API su /admin/api/keys.
Puoi condividere quale sia la necessità funzionale che stai cercando di affrontare?
Abbiamo il file login_12.py che testa la funzionalità di accesso a Discourse ogni 5 minuti.
Abbiamo dovuto aggiungere i cookie (cookies.pkl) in login_12.py per accedere correttamente.
Come abbiamo ottenuto i cookie (cookies.pkl)?
Abbiamo un altro file generate_cookies.py, in questo file abbiamo l’email e la password dell’utente codificate, usando questo generiamo i cookie per quell’utente specifico e scriviamo un file cookies.pkl.
Per generare i cookie utilizziamo un browser che vogliamo evitare e questo passaggio vogliamo farlo automaticamente tramite codice senza usare un browser.
Contenuto di generate_cookies.py
from selenium import webdriver
import undetected_chromedriver as uc
from selenium.webdriver.common.keys import Keys
import time
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import pickle
options = uc.ChromeOptions()
#options.add_argument('--headless')
options.add_argument("--disable-extensions")
options.add_argument("--disable-popup-blocking")
options.add_argument("--profile-directory=Default")
options.add_argument("--ignore-certificate-errors")
options.add_argument("--disable-plugins-discovery")
options.add_argument("--incognito")
options.add_argument("user_agent=DN")
if __name__ == "__main__": #Necessario solo per Windows (Bug in undetected_chromedriver)
driver = uc.Chrome(options=options)
# login
GMAIL = 'discourse.testing@gmail.com'
PASSWORD = 'discoursetest123'
driver.get("https://forum.discourse.org/")
print(driver.title)
WebDriverWait(driver, 20).until(EC.presence_of_element_located((By.XPATH, '/html/body')))
print('Homepage caricata')
WebDriverWait(driver, 20).until(EC.presence_of_element_located((By.CLASS_NAME, 'login-button')))
login = driver.find_elements_by_class_name("login-button")[0]
print(login)
login.send_keys(Keys.RETURN)
print(driver.current_url)
driver.get(driver.current_url)
print("email")
WebDriverWait(driver, 20).until(EC.presence_of_element_located((By.XPATH, '/html/body')))
print('Pagina email caricata')
#print(driver.page_source)
driver.find_element_by_xpath("/html/body/div[1]/div[1]/div[2]/div/div[2]/div/div/div[2]/div/div[1]/div/form/span/section/div/div/div[1]/div/div[1]/div/div[1]/input").send_keys(GMAIL)
driver.find_element_by_xpath("/html/body/div[1]/div[1]/div[2]/div/div[2]/div/div/div[2]/div/div[1]/div/form/span/section/div/div/div[1]/div/div[1]/div/div[1]/input").send_keys(Keys.RETURN)
print("Email inserita")
time.sleep(3)
WebDriverWait(driver, 20).until(EC.presence_of_element_located((By.XPATH, '/html/body')))
print('Pagina password caricata')
#print(driver.page_source)
driver.find_element_by_xpath("/html/body/div[1]/div[1]/div[2]/div/div[2]/div/div/div[2]/div/div[1]/div/form/span/section/div/div/div[1]/div[1]/div/div/div/div/div[1]/div/div[1]/input").send_keys(PASSWORD)
driver.find_element_by_xpath("/html/body/div[1]/div[1]/div[2]/div/div[2]/div/div/div[2]/div/div[1]/div/form/span/section/div/div/div[1]/div[1]/div/div/div/div/div[1]/div/div[1]/input").send_keys(Keys.RETURN)
print("Password inserita")
time.sleep(3)
WebDriverWait(driver, 20).until(EC.presence_of_element_located((By.XPATH, '/html/body')))
print('Accesso completato')
print(driver.title)
#print(driver.find_element_by_xpath("/html/body").get_attribute('innerHTML'))
if not "Discourse Forum" in driver.title:
raise Exception('Errore di accesso')
else:
print("Homepage caricata")
driver.get(driver.current_url+'/c/announcements/5')
WebDriverWait(driver, 20).until(EC.presence_of_element_located((By.XPATH, '/html/head/title')))
print('Tentativo pagina annunci')
print(driver.title)
if not "Latest Announcements topics - Discourse Forum" in driver.title:
raise Exception('Errore funzione di accesso')
print("Successo!")
pickle.dump( driver.get_cookies() , open("cookies2.pkl","wb"))
Questa è più una domanda su Python.
Puoi usare la libreria Requests in Python per effettuare le tue richieste. Supporta i cookie in vari modi, qui ci sono alcuni esempi. Ti consiglierei di usare un oggetto Session.
Se vuoi analizzare l’output HTML, puoi usare BeautifulSoup.
Quindi quello che stai cercando di realizzare è testare continuamente che i login funzionino? Non stai cercando di fare nulla. Vuoi solo assicurarti che se qualcuno prova ad accedere al tuo sito, funzionerà (probabilmente)?