共计 2323 个字符,预计需要花费 6 分钟才能阅读完成。
背景与痛点
传统爬虫技术(如 requests + BeautifulSoup)在静态页面抓取中表现优异,但当面对 ChatGPT 这类动态内容加载的网站时,往往力不从心。主要痛点包括:

- 动态生成内容无法直接获取:ChatGPT 的对话内容通过 JavaScript 动态渲染,传统爬虫只能获取空框架
- 反爬虫机制严格:OpenAI 部署了多层次防护(如 Cloudflare、行为检测),直接请求容易被封禁
- 交互模拟困难:对话需要保持会话状态,涉及 cookies 管理和多步操作
技术选型
在浏览器自动化工具中,主流选择有:
- Selenium
- 优点:生态成熟、文档丰富、支持多种浏览器
-
缺点:执行速度较慢,原生不支持无头浏览器并发
-
Playwright
- 优点:跨浏览器支持、自动等待机制、性能优于 Selenium
-
缺点:较新,社区资源相对较少
-
Puppeteer(Node.js 生态)
- 优点:与 Chrome 深度集成,执行效率高
- 缺点:仅支持 JavaScript
对于 Python 技术栈,推荐组合:Selenium + ChromeDriver(稳定)或 Playwright-Python(高效)。本文以 Selenium 为例演示。
核心实现
环境准备
# 安装依赖
# pip install selenium webdriver-manager
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from webdriver_manager.chrome import ChromeDriverManager
初始化 WebDriver
def init_driver(headless=True):
options = webdriver.ChromeOptions()
if headless:
options.add_argument('--headless')
options.add_argument('--disable-blink-features=AutomationControlled')
driver = webdriver.Chrome(ChromeDriverManager().install(),
options=options
)
return driver
登录与对话模拟
def chat_with_gpt(driver, prompt):
# 访问 ChatGPT 页面
driver.get('https://chat.openai.com')
# 等待输入框加载(最多等待 10 秒)input_box = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.TAG_NAME, 'textarea'))
)
# 输入问题并提交
input_box.send_keys(prompt)
submit_btn = driver.find_element(By.CSS_SELECTOR, 'button[data-testid="send-button"]'
)
submit_btn.click()
# 等待回复生成(检测停止动画)WebDriverWait(driver, 30).until(EC.invisibility_of_element_located((By.CSS_SELECTOR, '.result-streaming'))
)
# 获取最新回复
responses = driver.find_elements(By.CSS_SELECTOR, '[data-testid^="conversation-turn"]')
return responses[-1].text
性能优化
- 智能等待策略
- 使用显式等待(WebDriverWait)替代固定 sleep
-
关键示例:等待特定元素消失(如
.result-streaming) -
并发控制
- 通过多线程运行多个 driver 实例
-
注意:每个线程需要独立的用户数据目录
-
缓存复用
- 保存 cookies 避免重复登录
- 示例代码:
# 登录后保存 cookies import pickle pickle.dump(driver.get_cookies(), open('cookies.pkl', 'wb')) # 后续会话加载 cookies for cookie in pickle.load(open('cookies.pkl', 'rb')): driver.add_cookie(cookie)
安全性考量
- 遵守 robots.txt:检查 https://chat.openai.com/robots.txt 的限制条款
- 请求频率控制 :
- 单个账号请求间隔建议 ≥30 秒
- 避免连续快速提问
- 行为模式 :
- 添加随机延迟(2- 5 秒)
- 模拟人类鼠标移动轨迹
避坑指南
- 常见错误 1:元素定位失败
- 现象:NoSuchElementException
-
解决:
- 确认页面完全加载(检查网络请求)
- 使用更稳定的定位方式(如 data-testid)
-
常见错误 2:会话超时
- 现象:突然跳转登录页
-
解决:
- 定期检查会话有效性
- 实现自动重新登录机制
-
常见错误 3:IP 被封禁
- 现象:出现验证码或拒绝访问
- 解决:
- 使用住宅代理(非数据中心 IP)
- 限制单 IP 请求频率
总结
通过本文的实践,我们可以发现 WebDriver 在爬取动态内容时的独特优势。建议读者可以尝试:
- 结合 Playwright 提升执行效率
- 集成代理池解决封禁问题
- 使用更精细的行为模拟策略
期待大家在评论区分享自己的优化方案和实战经验!
正文完
