共计 2421 个字符,预计需要花费 7 分钟才能阅读完成。
背景与痛点
ChatGPT 作为当前最流行的 AI 对话平台,其数据对研究者和开发者具有重要价值。然而,直接爬取 ChatGPT 数据会遇到几个主要问题:

- 严格的反爬机制:包括 IP 限制、请求频率检测、浏览器指纹验证等
- 动态内容加载:部分内容通过 JavaScript 异步加载,传统爬虫难以捕获
- 验证码挑战:频繁请求会触发验证码验证
- 数据结构复杂:对话内容嵌套在多层级 DOM 结构中
技术方案对比
在 Python 生态中,主要有两种方案可用于爬取 ChatGPT:
- Requests+BeautifulSoup 组合
- 优点:轻量级、速度快、资源消耗低
-
缺点:无法直接执行 JavaScript
-
Selenium 等浏览器自动化工具
- 优点:可以完整渲染页面,获取动态内容
- 缺点:速度慢、资源占用高、容易被检测
对于 ChatGPT 这种动态内容较多的网站,建议采用混合方案:使用 Requests 获取基础内容,配合少量 JavaScript 逆向分析获取动态数据。
核心实现
模拟浏览器请求头
正确的请求头是绕过基础反爬的关键。以下是需要设置的重要字段:
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)',
'Accept': 'text/html,application/xhtml+xml',
'Accept-Language': 'en-US,en;q=0.9',
'Referer': 'https://chat.openai.com/',
'DNT': '1' # 不追踪
}
处理动态加载内容
ChatGPT 的对话内容通常通过 API 异步加载。可以通过以下步骤获取:
- 使用浏览器开发者工具监控 XHR 请求
- 分析 API 端点规律和参数
- 直接模拟这些 API 请求获取 JSON 数据
使用代理 IP 池
为防止 IP 被封,建议使用代理 IP 并实现自动切换:
import random
proxies = [{'http': 'http://proxy1.example.com:8080'},
{'http': 'http://proxy2.example.com:8080'}
]
current_proxy = random.choice(proxies)
response = requests.get(url, headers=headers, proxies=current_proxy)
完整代码示例
import requests
from bs4 import BeautifulSoup
import time
import random
# 基础配置
BASE_URL = 'https://chat.openai.com/'
HEADERS = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)',
'Accept-Language': 'en-US,en;q=0.9'
}
# 获取会话 ID
session = requests.Session()
response = session.get(BASE_URL, headers=HEADERS)
soup = BeautifulSoup(response.text, 'html.parser')
# 解析对话内容
def parse_conversation(html):
soup = BeautifulSoup(html, 'html.parser')
messages = []
for item in soup.select('.conversation-item'):
role = item.select_one('.role').text
content = item.select_one('.content').text
messages.append({'role': role, 'content': content})
return messages
# 主爬取流程
def main():
try:
response = session.get(BASE_URL + 'api/conversations', headers=HEADERS)
conversations = response.json()
for conv in conversations['items']:
conv_id = conv['id']
conv_url = f"{BASE_URL}api/conversation/{conv_id}"
# 随机延迟防止封禁
time.sleep(random.uniform(1, 3))
conv_response = session.get(conv_url, headers=HEADERS)
messages = parse_conversation(conv_response.text)
# 存储或处理数据
print(f"获取到对话 {conv_id},共 {len(messages)} 条消息")
except Exception as e:
print(f"发生错误: {str(e)}")
if __name__ == '__main__':
main()
性能优化
- 并发请求:使用
aiohttp实现异步请求 - 缓存机制:对已爬取的对话 ID 进行记录,避免重复爬取
- 请求间隔:随机化请求间隔,模拟人类操作模式
- 断点续爬:保存爬取状态,方便中断后继续
避坑指南
- 验证码触发:保持合理请求频率,遇到验证码时暂停爬取
- 数据解析失败:定期检查 DOM 结构变化,更新选择器
- IP 被封:立即切换代理,降低请求频率
- 会话失效:定期检查会话 cookie 有效性
安全与合规
在爬取 ChatGPT 数据时,务必注意:
- 遵守 robots.txt 规定
- 限制爬取频率,避免影响服务正常运行
- 不爬取私人对话内容
- 合理使用数据,遵守相关法律法规
思考题
- 如何识别和处理 ChatGPT 新引入的反爬机制?
- 在大规模爬取场景下,如何设计分布式爬虫架构?
- 除了本文介绍的方法,还有哪些技术可以用于获取动态加载内容?
希望通过这篇文章,你能掌握 Python 爬取 ChatGPT 数据的核心技巧。在实际应用中,请始终牢记爬虫伦理,合理使用技术。
正文完
