Я написал код для генерации куки-файлов (_forum_session и _t) с помощью Selenium и Python. Однако в этом случае также необходимо вручную ввести номер телефона и OTP для подтверждения. Я хочу сделать генерацию куки полностью автоматической через код, без необходимости что-либо заполнять вручную. Как этого достичь?
Не могли бы вы вернуться назад и описать, какую проблему решит наличие этих файлов cookie?
Чего вы пытаетесь достичь? Вы пытаетесь настроить аутентификацию Discourse в вашем приложении? Возможно, стоит посмотреть на DiscourseConnect — официальное решение для единого входа (SSO) для Discourse?
С помощью generate_cookies.py я получил файл cookies.pkl, который использую для автоматического входа каждые 5 минут.
У меня есть файл login_12.py, который вызывается каждые 5 минут для проверки входа.
login_12.py (ниже приведён пример кода):
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"))
Хочу получать куки автоматически без использования браузера, чтобы весь процесс был полностью автоматизирован.
Вы всё ещё описываете предлагаемое решение, а не проблему, которую пытаетесь решить.
Зачем вам нужны куки, если браузер не требуется?
Вы пытаетесь разрешить вашему внешнему приложению «<сделать что-то>» с Discourse? Возможно, стоит просто использовать ключ API?
Зачем нужны файлы cookie?
Ответ — потому что без добавления файла cookies.pkl мы не можем войти через файл login_12.py.
На данный момент для генерации файлов cookie необходимо вручную вводить номер телефона и OTP в браузере, управляемом Chrome Driver. Я не хочу ничего вводить вручную, поэтому не хочу использовать браузер для генерации файлов cookie.
generate_cookies.py (пример кода)
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")
# вход
GMAIL = 'discourse.mytest@ymail.com'
PASSWORD = 'test123'
driver.get("https://forun.discourse.org/")
print(driver.title)
WebDriverWait(driver, 20).until(EC.presence_of_element_located((By.XPATH, '/html/body')))
print('Главная страница загружена')
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 загружена')
#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 введен")
time.sleep(3)
WebDriverWait(driver, 20).until(EC.presence_of_element_located((By.XPATH, '/html/body')))
print('Страница пароля загружена')
#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("Пароль введен")
time.sleep(3)
WebDriverWait(driver, 20).until(EC.presence_of_element_located((By.XPATH, '/html/body')))
print('Вход выполнен')
print(driver.title)
#print(driver.find_element_by_xpath("/html/body").get_attribute('innerHTML'))
if not "Discourse Forum" in driver.title:
raise Exception('Ошибка входа')
else:
print("Главная страница загружена")
driver.get(driver.current_url+'/c/announcements/5')
WebDriverWait(driver, 20).until(EC.presence_of_element_located((By.XPATH, '/html/head/title')))
print('Пытаемся открыть страницу объявлений')
print(driver.title)
В итоге нужно добиться следующего.
if (получить срок действия из локального хранилища headless-браузера >= текущее время)
{
запустить генерацию файлов cookie (проблема с этой частью: автоматизация пока не работает полностью, некоторые действия выполняются вручную)
загрузить файл cookies.pkl в соответствующую директорию
}else{
запустить login_12.py для входа
}
получить доступ к локальному хранилищу headless-браузера Chrome
добавить/обновить срок действия в переменной локального хранилища
Как и почему?
Можно автоматически подставить номер телефона (где именно это запрашивается?) и отключить OTP для этого пользователя?
@RGJ Есть ли какие-либо конечные точки или API, которые мы можем вызвать, чтобы получить действительный токен доступа для входа?
Если ваша цель — позволить пользователям входить в Discourse через ваше другое приложение или входить в ваше другое приложение через Discourse, то вам нужно реализовать DiscourseConnect, ссылку на который я дал выше. На этой странице вы найдёте документацию и примеры кода.
Да, мне всё ещё не совсем понятно, чего именно вы пытаетесь добиться.
Если вам нужно интегрировать другую веб-страницу, используя аутентификацию Discourse как источник истины, вы можете использовать Discourse в качестве провайдера SSO.
Если вам нужно выполнять вызовы между серверами к API Discourse, вы можете создать ключи API на странице /admin/api/keys.
Можете ли вы описать функциональную задачу, которую вы пытаетесь решить?
У нас есть файл login_12.py, который проверяет функциональность входа в Discourse каждые 5 минут.
Нам пришлось добавить файлы cookie (cookies.pkl) в login_12.py для корректного входа.
Как мы получили файлы cookie (cookies.pkl)?
У нас есть другой файл generate_cookies.py, в котором жестко заданы email и пароль пользователя. Используя их, мы генерируем файлы cookie для этого конкретного пользователя и записываем их в файл cookies.pkl.
При генерации cookie мы используем браузер, чего мы хотим избежать. Этот шаг нужно выполнить автоматически через код без использования браузера.
Содержимое файла 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”: #Требуется только для Windows (баг в undetected_chromedriver)
driver = uc.Chrome(options=options)
# вход
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('Главная страница загружена')
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 загружена')
#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 введен")
time.sleep(3)
WebDriverWait(driver, 20).until(EC.presence_of_element_located((By.XPATH, '/html/body')))
print('Страница пароля загружена')
#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("Пароль введен")
time.sleep(3)
WebDriverWait(driver, 20).until(EC.presence_of_element_located((By.XPATH, '/html/body')))
print('Вход выполнен')
print(driver.title)
#print(driver.find_element_by_xpath("/html/body").get_attribute('innerHTML'))
if not "Discourse Forum" in driver.title:
raise Exception('Ошибка входа')
else:
print("Главная страница загружена")
driver.get(driver.current_url+'/c/announcements/5')
WebDriverWait(driver, 20).until(EC.presence_of_element_located((By.XPATH, '/html/head/title')))
print('Пытаемся открыть страницу объявлений')
print(driver.title)
if not "Latest Announcements topics - Discourse Forum" in driver.title:
raise Exception('Ошибка функции входа')
print("Успех!")
pickle.dump( driver.get_cookies() , open("cookies2.pkl","wb"))
Это скорее вопрос по Python.
Вы можете использовать библиотеку Requests в Python для выполнения запросов. Она поддерживает работу с cookies различными способами, вот несколько примеров. Рекомендую использовать объект Session.
Если вы хотите распарсить HTML-вывод, можно использовать BeautifulSoup.
Итак, ваша цель — постоянно проверять, что вход работает? Вы не пытаетесь что-то сделать. Вы просто хотите убедиться, что если кто-то попытается войти на ваш сайт, это (скорее всего) сработает?