共计 1660 个字符,预计需要花费 5 分钟才能阅读完成。
背景痛点分析
直接爬取 ChatGPT 网页端面临三大技术难点:

- 动态渲染 :前端采用 React 等框架生成动态内容,传统爬虫无法直接获取有效数据
- Cloudflare 防护 :包括 5 秒盾、人机验证等多层防御机制,常规请求会被拦截
- 会话维持 :需要处理 cookies、JWT 令牌等认证凭证的自动更新
技术方案对比
方案一:浏览器自动化工具
- Selenium/Playwright
优点: - 完全模拟用户操作行为
- 可处理复杂交互场景
缺点: - 资源占用高(每个实例需启动完整浏览器)
- 运行速度慢(受页面加载时间制约)
方案二:API 逆向工程
- 直接调用接口
优点: - 请求效率高(绕过 UI 渲染环节)
- 资源消耗低
缺点: - 需要逆向分析接口协议
- 需持续维护参数加密逻辑
核心实现步骤
1. 请求头伪装
使用动态 UA 生成器:
from fake_useragent import UserAgent
ua = UserAgent()
headers = {
'User-Agent': ua.random,
'Accept-Language': 'en-US,en;q=0.9'
}
2. 代理 IP 池实现
import requests
from itertools import cycle
proxies = [
'http://proxy1.example.com:8080',
'http://proxy2.example.com:8080'
]
proxy_pool = cycle(proxies)
session = requests.Session()
session.proxies = {'http': next(proxy_pool)}
3. 请求间隔控制
指数退避算法实现:
import time
import random
def exponential_backoff(retries):
base_delay = 1
max_delay = 60
delay = min(max_delay, base_delay * (2 ** retries) + random.random())
time.sleep(delay)
完整爬虫类实现
import aiohttp
import asyncio
from typing import Optional, Dict
class ChatGPTScraper:
"""异步爬虫核心类"""
def __init__(self, max_retries=3):
self.max_retries = max_retries
self.session = None
async def initialize(self):
"""初始化会话"""
self.session = aiohttp.ClientSession(headers=self._generate_headers(),
timeout=aiohttp.ClientTimeout(total=30)
)
async def fetch(self, url: str, params: Optional[Dict] = None) -> str:
"""执行请求"""
for attempt in range(self.max_retries):
try:
async with self.session.get(url, params=params) as response:
response.raise_for_status()
return await response.text()
except Exception as e:
if attempt == self.max_retries - 1:
raise
await asyncio.sleep(2 ** attempt) # 指数退避
生产环境考量
- 分布式架构 :采用 Scrapy-Redis 实现多节点任务分发
- 法律合规 :
- 遵守 robots.txt 协议
- 控制请求频率(建议 <1req/s)
- 数据去重 :使用 BloomFilter 处理重复内容
常见问题应对方案
- 触发人机验证 :
- 立即切换代理 IP
- 暂停采集 1 - 2 小时
- 账号被封禁 :
- 更换认证令牌
- 模拟真实用户行为轨迹
- 数据格式变更 :
- 建立自动化监测机制
- 维护多版本解析器
延伸思考方向
- 生成式 AI 内容的数据权属认定
- 训练数据采集的合规边界
- 反爬技术对抗的伦理讨论
正文完
