Escrevi um código para gerar cookies (_forum_session e _t) usando Selenium e Python. Mas neste caso, também devemos preencher manualmente o número de telefone e o OPT para validar. Quero gerar cookies de forma totalmente automática através de código, não quero preencher nada manualmente. Como posso conseguir isso?
Você pode voltar e descrever qual problema a posse desses cookies resolverá?
O que você está tentando realizar? Você está tentando autenticar o Discourse em seu aplicativo? Talvez dê uma olhada em DiscourseConnect - Single Sign-On Oficial para Discourse (sso)?
Através do generate_cookies.py, recebi o cookies.pkl que uso para testar o login automaticamente a cada 5 minutos.
Então, tenho um arquivo login_12.py que é chamado a cada 5 minutos para testar meus logins.
login_12.py (abaixo está um exemplo de código)
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"))
Quero gerar cookies automaticamente sem usar o navegador, para que todo o processo seja automático.
Você ainda está descrevendo sua solução proposta em vez do problema que você está tentando resolver.
Por que você precisa dos cookies se não precisa de um navegador?
Você está tentando fazer com que seu aplicativo externo possa fazer algo no Discourse? Talvez apenas usar uma chave de API?
Por que você precisa dos cookies?
Resposta: porque sem adicionar o arquivo cookies.pkl, não conseguimos fazer login através do arquivo login_12.py.
No momento, para gerar cookies, devemos preencher o número de telefone e o OTP manualmente no navegador Chrome Driver. Eu não quero preencher nada manualmente, é por isso que não quero usar o navegador para gerar cookies.
generate_cookies.py (código de exemplo)
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 loaded')
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('Email page loaded')
#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 entered")
time.sleep(3)
WebDriverWait(driver, 20).until(EC.presence_of_element_located((By.XPATH, '/html/body')))
print('Password page loaded')
#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 entered")
time.sleep(3)
WebDriverWait(driver, 20).until(EC.presence_of_element_located((By.XPATH, '/html/body')))
print('Login completed')
print(driver.title)
#print(driver.find_element_by_xpath("/html/body").get_attribute('innerHTML'))
if not "Discourse Forum" in driver.title:
raise Exception('login Error')
else:
print("Homepage loaded")
driver.get(driver.current_url+'/c/announcements/5')
WebDriverWait(driver, 20).until(EC.presence_of_element_located((By.XPATH, '/html/head/title')))
print('Trying announcements page')
print(driver.title)
Finalmente, quero alcançar isso.
if (obter expiração do armazenamento local do navegador headless >= agora)
{
#executar generate cookies (problema com esta parte para automatizar, atualmente algumas partes são manuais)
#carregar o arquivo cookies.pkl para o diretório apropriado
}else{
#executar lopin_12.py para fazer login
}
#acessar o armazenamento local para o navegador headless chrome
#adicionar/atualizar a data de expiração na variável de armazenamento local
Como e por quê?
Você pode preencher o número de telefone (onde isso está sendo solicitado?) automaticamente e desativar o OTP para esse usuário?
@RGJ Existe algum endpoint ou API disponível que possamos chamar para obter um token de acesso de login válido?
Se o que você está tentando fazer é permitir que as pessoas façam login no Discourse usando seu outro aplicativo, ou fazer login no seu outro aplicativo usando o Discourse, então você quer implementar o DiscourseConnect, que eu linkei acima. Você pode ver essa página para documentação e exemplos de código.
Sim, ainda não está claro para mim o que exatamente você está tentando alcançar.
Se você precisar integrar outra página da web usando a autenticação do Discourse como fonte de verdade, você pode usar Discourse como provedor de SSO.
Se você precisar fazer chamadas de servidor para servidor para a API do Discourse, você pode criar chaves de API em /admin/api/keys.
Você pode compartilhar qual é a necessidade funcional que você está tentando resolver?
Temos o arquivo login_12.py que testa a funcionalidade de login do Discourse a cada 5 minutos.
Tivemos que adicionar cookies (cookies.pkl) em login_12.py para fazer login corretamente.
Como obtivemos os cookies (cookies.pkl)?
Temos outro arquivo, generate_cookies.py. Neste arquivo, temos o e-mail e a senha do usuário codificados, usando isso geramos cookies para aquele usuário específico e escrevemos um arquivo cookies.pkl.
Para gerar cookies, usamos um navegador que queremos evitar e esta etapa queremos fazer automaticamente através de código, sem usar um navegador.
Conteúdo de 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__": #Necessário apenas para Windows (Bug em 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 loaded')
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('Email page loaded')
#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 entered")
time.sleep(3)
WebDriverWait(driver, 20).until(EC.presence_of_element_located((By.XPATH, '/html/body')))
print('Password page loaded')
#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 entered")
time.sleep(3)
WebDriverWait(driver, 20).until(EC.presence_of_element_located((By.XPATH, '/html/body')))
print('Login completed')
print(driver.title)
#print(driver.find_element_by_xpath("/html/body").get_attribute('innerHTML'))
if not "Discourse Forum" in driver.title:
raise Exception('login Error')
else:
print("Homepage loaded")
driver.get(driver.current_url+'/c/announcements/5')
WebDriverWait(driver, 20).until(EC.presence_of_element_located((By.XPATH, '/html/head/title')))
print('Trying announcements page')
print(driver.title)
if not "Latest Announcements topics - Discourse Forum" in driver.title:
raise Exception('login Error function')
print("Success!")
pickle.dump( driver.get_cookies() , open("cookies2.pkl","wb"))
Esta é mais uma pergunta sobre Python.
Você pode usar a biblioteca Requests em Python para fazer suas requisições. Ela suporta cookies de várias maneiras, aqui estão alguns exemplos. Eu recomendaria que você usasse um objeto Session.
Se você quiser analisar a saída HTML, pode usar BeautifulSoup.
Então, o que você está tentando realizar é testar continuamente se os logins funcionam? Você não está tentando fazer nada. Você só quer ter certeza de que, se alguém tentar fazer login no seu site, ele funcionará (provavelmente)?