ChatGPT对话记录导出实战:Python脚本与API自动化方案

1次阅读
没有评论

共计 2167 个字符,预计需要花费 6 分钟才能阅读完成。

image.webp

背景痛点

在日常开发中,很多开发者会频繁使用 ChatGPT 进行技术讨论或问题解决,但官方并没有提供便捷的批量导出功能。这导致了一些常见需求无法满足:

ChatGPT 对话记录导出实战:Python 脚本与 API 自动化方案

  • 数据分析:想要统计高频问题或对话趋势
  • 合规审计:企业用户需要留存沟通记录
  • 知识沉淀:将优质对话整理为内部知识库
  • 个人备份:防止重要对话意外丢失

网页端和移动端都只能手动复制单条对话,当对话量较大时,这种方式的效率极低。

技术方案对比

方案 1:基于 Playwright 的网页自动化抓取

优点:
– 不需要 OpenAI API 权限
– 可以获取到完整的对话渲染结果(包括代码高亮等格式)

缺点:
– 需要处理动态加载和反爬机制
– 网页结构变更可能导致脚本失效
– 执行效率相对较低

方案 2:OpenAI 官方 API 调用

优点:
– 数据格式规范统一
– 执行效率高
– 官方支持的稳定接口

缺点:
– 需要有效的 API 密钥
– 有调用频率限制
– 部分历史对话可能无法获取

核心实现

Playwright 方案关键技术点

  1. 模拟登录:
  2. 使用浏览器上下文保存登录状态
  3. 处理可能的验证码挑战

  4. 滚动加载:

  5. 监测页面高度变化
  6. 判断加载完成的标志

  7. 反爬对策:

  8. 随机化操作间隔
  9. 使用真人操作模式

API 方案关键技术点

  1. 分页获取:
  2. 使用 after 参数实现游标分页
  3. 处理空响应终止条件

  4. 速率控制:

  5. 实现指数退避重试
  6. 响应头解析配额信息

代码示例

Playwright 实现核心代码

import asyncio
from playwright.async_api import async_playwright

async def export_chat_histories():
    async with async_playwright() as p:
        # 启动浏览器,建议使用 chromium
        browser = await p.chromium.launch(headless=False)
        context = await browser.new_context()
        page = await context.new_page()

        # 模拟登录过程
        await page.goto('https://chat.openai.com')
        await page.fill('#username', 'your_email')
        await page.click('button[type="submit"]')

        # 等待对话列表加载
        await page.wait_for_selector('.conversation-list')

        # 滚动加载所有历史记录
        last_height = 0
        while True:
            current_height = await page.evaluate('document.body.scrollHeight')
            if current_height == last_height:
                break
            last_height = current_height
            await page.evaluate('window.scrollTo(0, document.body.scrollHeight)')
            await asyncio.sleep(2)  # 适当延迟防止被拦截

        # 提取对话内容
        conversations = await page.query_selector_all('.conversation-item')
        for conv in conversations:
            title = await conv.inner_text()
            print(f"发现对话: {title}")

        await browser.close()

API 实现核心代码

import openai
import time
import backoff

@backoff.on_exception(backoff.expo, openai.error.RateLimitError)
async def get_chat_history(api_key, after=None):
    openai.api_key = api_key

    try:
        params = {"limit": 100}
        if after:
            params["after"] = after

        # 获取对话列表
        conversations = await openai.ChatCompletion.list(**params)

        # 处理获取到的数据
        for conv in conversations.data:
            print(f"对话 ID: {conv.id}, 创建时间: {conv.created_at}")

        # 返回最后一条记录的 ID 用于分页
        if conversations.data:
            return conversations.data[-1].id
        return None

    except openai.error.APIError as e:
        print(f"API 错误: {e}")
        raise

生产环境建议

  1. 性能优化:
  2. 对于 API 方案,合理设置并发数(建议 5 -10 个并发)
  3. 使用连接池管理 HTTP 请求

  4. 安全性:

  5. API 密钥使用环境变量或密钥管理服务
  6. 实施最小权限原则

  7. 稳定性:

  8. 实现断点续传机制
  9. 记录成功导出的最后位置

延伸思考

  1. 数据管道建设:
  2. 可以将导出的 JSON 数据直接摄入 ELK 栈
  3. 使用 Logstash 进行数据清洗和转换

  4. 企业级方案:

  5. 实现基于角色的访问控制
  6. 对话记录加密存储
  7. 操作审计日志

在实际项目中,两种方案可以结合使用 – 用 API 获取基础数据,再用 Playwright 补充渲染细节。根据具体需求场景选择最合适的方案,或者组合使用取长补短。

正文完
 0
评论(没有评论)