Сильный ИИ. Элира2. Сохранение диалогов ChatGPT
Всем привет!
В этой статье я расскажу о том, как можно сохранить диалоги в ChatGPT вместе с изображениями из чата!
Несмотря на уже довольно долгое существование ChatGPT в нем до сих пор отсутствует функция сохранения диалогов с изображениями. Более того, при наличии изображений в диалоге, ссылка для сохранения вообще не создается. Именно поэтому я решил создать скрипт, который позволит сохранять диалоги напрямую через веб-интерфейс ChatGPT, используя Selenium.
Подготовка
Для начала необходимо установить необходимые зависимости. Создаем файл requirements.txt с содержимым:
undetected-chromedriver
selenium
requests
Затем устанавливаем зависимости с помощью команды (в консоли): pip install -r requirements.txt
Далее создаем файл credentials.txt, в который записываем логин и пароль для автоматического входа в ChatGPT:
myemail@example.com
mypassword
Создание скрипта
Начнем с импорта необходимых библиотек и чтения учетных данных:
import os
import time
import requests
from undetected_chromedriver import Chrome, ChromeOptions
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
# Чтение учетных данных из файла
with open('credentials.txt', 'r', encoding='utf-8') as f:
credentials = f.read().splitlines()
email = credentials[0]
password = credentials[1]
Для автоматизации браузера (и обхода cloudflare) используем библу undetected_chromedriver.
Настраиваем его и открываем страницу для входа в ChatGPT:
# Настройка undetected_chromedriver
options = ChromeOptions()
options.add_argument('--no-sandbox')
options.add_argument('--disable-dev-shm-usage')
with Chrome(options=options) as driver:
driver.get('https://chat.openai.com/')
wait = WebDriverWait(driver, 10)
login_button = wait.until(EC.element_to_be_clickable((By.XPATH, '/html/body/div[1]/div[1]/div[2]/div[1]/div/div/button[1]/div/span')))
login_button.click()
# Ввод логина
email_field = wait.until(EC.presence_of_element_located((By.XPATH, '/html/body/div/div/main/section/div[2]/div[1]/input')))
email_field.send_keys(email)
next_button = driver.find_element(By.XPATH, '/html/body/div/div/main/section/div[2]/button')
next_button.click()
# Ввод пароля
password_field = wait.until(EC.presence_of_element_located((By.XPATH, '/html/body/div[1]/main/section/div/div/div/form/div[1]/div/div[2]/div/input')))
password_field.send_keys(password)
login_button = driver.find_element(By.XPATH, '/html/body/div[1]/main/section/div/div/div/form/div[2]/button')
login_button.click()
input("Выберите нужный диалог и нажмите Enter для продолжения...")
Создаем папки для сохранения данных и функции для сохранения текста и скачивания файлов:
# Создание папок для сохранения данных
if not os.path.exists('Диалог'):
os.makedirs('Диалог/Вложения')
# Функция для сохранения текста сообщения
def save_text(message, filename):
with open(filename, 'w', encoding='utf-8') as f:
f.write(message)
# Функция для скачивания файла по URL
def download_file(url, dest_path):
response = requests.get(url)
with open(dest_path, 'wb') as f:
f.write(response.content)
Далее создаем основной HTML-файл для сохранения диалогов. В HTML включены стили, сделанные в цветах веб-интерфейса ChatGPT (для крОсоты):
# Создание основного HTML файла
html_content = """
Диалог
×
"""
Теперь приступаем к сбору всех сообщений и их обработке. Будем определять «авторство» сообщения и обрабатывать текст, код и изображения отдельно:
# Инициализация счетчиков
total_messages = 0
user_messages = 0
ai_messages = 0
skipped_msg = 0
# Сбор всех сообщений
messages = driver.find_elements(By.XPATH, '//div[contains(@class, "group") and contains(@class, "flex") and not(contains(@class, "h-48"))]')
for idx, message in enumerate(messages):
if not message.text.strip():
skipped_msg += 1
continue # Пропускаем пустые сообщения
total_messages += 1
role = ""
# Проверка, является ли автор сообщения пользователем или ИИ
try:
author_role_element = message.find_element(By.XPATH, './/div[@data-message-author-role]')
author_role = author_role_element.get_attribute('data-message-author-role')
if author_role == 'user':
user_messages += 1
role = "Пользователь"
role_class = "user-message"
elif author_role == 'assistant':
ai_messages += 1
role = "ИИ"
role_class = "ai-message"
else:
continue # Пропускаем неизвестные роли
except:
continue # Пропускаем сообщения без атрибута data-message-author-role
# Заменяем роль на значок для ИИ
if role == "ИИ":
role_icon = ""
role_html = f"{role_icon}
"
else:
role_html = ""
html_content += f" »
Не забудем корректно закрыть HTML-структуру, сохранить основной HTML-файл и вывести статистику:
# Закрытие HTML структуры
html_content += """
"""
# Сохранение основного HTML файла
with open('Диалог/диалог.html', 'w', encoding='utf-8') as f:
f.write(html_content)
# Вывод статистики
print(f"Всего сообщений: {total_messages}")
print(f"Сообщений пользователя: {user_messages}")
print(f"Сообщений ИИ: {ai_messages}")
print("Диалог сохранен.")
Ссылка на репо с исходным кодом:
https://github.com/Devastor/DevastorSaveDialogues_ChatGPT
там же можно скачать файл иконки (для обозначения ИИ в финальном диалоге)
Что можно (и нужно) улучшить
Добавить возможность сохранения не только изображений, но и других форматов вложений, например, таблицы xls, csv (другие вложения живут в чате недолго, в отличие от таблиц).
Пофиксить ошибку «OSError: [WinError 6] Неверный дескриптор», которая вылетает после сохранения диалога (у меня не получилось, хотя я не особо старался, ибо лень, и работе скрипта не мешает, это должно быть довольно просто).
Добавить сохранение всех диалогов аккаунта в цикле (легко).
Добавить сохранение названия диалога (не так тривиально, как кажется — нужно как-то придумать, каким образом ловить имя контейнера того диалога, который выбран).
Убрать лишнюю кнопку «Копировать» из правого верхнего угла :)
Сделать логи отключаемыми (лучше всего прописать в args)
Habrahabr.ru прочитано 4383 раза