Python WebDriver 爬取 ChatGPT 的实战指南与避坑策略

2次阅读
没有评论

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

image.webp

1. 背景痛点分析

ChatGPT 作为基于 AJAX 的动态网页,其核心内容通过 JavaScript 异步加载,传统 requests 库无法直接获取有效数据。实际爬取时会遇到三个主要难点:

Python WebDriver 爬取 ChatGPT 的实战指南与避坑策略

  • 动态元素延迟加载 :对话内容需等待 API 响应后才渲染到 DOM,直接获取会出现元素不存在的情况
  • Cloudflare 反爬 :连续高频访问会触发 5 秒人机验证,甚至封禁 IP
  • 行为检测机制 :固定的操作间隔和线性鼠标轨迹会被识别为机器人行为

2. 技术选型对比

2.1 Selenium 优势

  • 成熟的浏览器自动化框架,支持 Chrome/Firefox/Edge 等多平台
  • 完善的等待机制(显式 / 隐式等待)
  • 丰富的模拟输入 API(键盘 / 鼠标操作)

2.2 Playwright 特点

  • 更快的执行速度(直接通过 CDP 协议控制浏览器)
  • 内置自动等待功能
  • 支持多语言(Python/Java/C#)

最终选择 Selenium 的原因:社区资源丰富,遇到问题更容易找到解决方案

3. 核心实现方案

3.1 动态元素定位策略

推荐使用 CSS 选择器 + 显式等待组合方案:

from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

# 等待消息框出现
message_box = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.CSS_SELECTOR, "div[role='presentation']"))
)

3.2 会话保持技巧

  1. 首次登录后保存 cookies:

    import pickle
    
    # 登录后保存
    pickle.dump(driver.get_cookies(), open("cookies.pkl", "wb"))
    
    # 后续会话复用
    cookies = pickle.load(open("cookies.pkl", "rb"))
    for cookie in cookies:
        driver.add_cookie(cookie)

  2. 定期检测登录状态,遇到失效自动重新认证

3.3 人类行为模拟

from selenium.webdriver.common.action_chains import ActionChains
import random
import time

# 随机延迟(1- 3 秒)time.sleep(random.uniform(1, 3))  

# 非线性鼠标移动
actions = ActionChains(driver)
actions.move_to_element_with_offset(element, 
    random.randint(5,15), 
    random.randint(5,15))
actions.perform()

4. 完整代码示例

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time
import random

# 浏览器配置
chrome_options = Options()
chrome_options.add_argument("--user-agent=Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36")
chrome_options.add_argument("--window-size=1920,1080")

driver = webdriver.Chrome(options=chrome_options)

try:
    # 访问登录页
    driver.get("https://chat.openai.com")

    # 等待登录完成(手动操作)WebDriverWait(driver, 120).until(EC.url_contains("/chat")
    )

    # 对话交互示例
    for i in range(3):
        # 定位输入框
        input_box = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "textarea#prompt-textarea"))
        )

        # 模拟人类输入速度
        for char in f"测试问题 {i}":
            input_box.send_keys(char)
            time.sleep(random.uniform(0.1, 0.3))

        # 随机延迟后提交
        time.sleep(random.uniform(1, 2))
        input_box.submit()

        # 等待响应完成
        WebDriverWait(driver, 30).until(EC.presence_of_element_located((By.CSS_SELECTOR, "div[class*='request-:r']"))
        )

        # 获取响应内容
        responses = driver.find_elements(By.CSS_SELECTOR, "div[class*='response-:r']")
        print(f"响应内容: {responses[-1].text}")

        # 操作间隔
        time.sleep(random.uniform(5, 10))

except Exception as e:
    print(f"发生错误: {str(e)}")
finally:
    driver.quit()

5. 性能与安全优化

5.1 IP 轮换方案

  • 使用住宅代理服务(Luminati/StormProxies)
  • 每个会话更换 IP:
    chrome_options.add_argument(f"--proxy-server=http://{get_random_proxy()}")

5.2 请求频率控制

  • 遵循 30/30 规则:每 30 分钟不超过 30 次请求
  • 动态调整间隔:
    delay = base_delay * (1 + random.random())  # 随机波动 

5.3 验证码处理

  • 使用 2Captcha 等付费服务
  • 自动检测验证码出现:
    if "验证码" in driver.page_source:
        solve_captcha()

6. 常见问题解决方案

6.1 XPath 失效问题

  • 避免使用绝对路径,改用相对路径
  • 示例改进:
    # 不推荐
    //*[@id="__next"]/div/div[2]/div[2]/div/div[3]/div/div/div
    
    # 推荐
    //div[contains(@class, 'response-')]

6.2 内存泄漏预防

  • 及时清理无用的 WebElement 引用
  • 定期重启浏览器实例(每 2 小时)

6.3 版本兼容性

  • 使用 WebDriverManager 自动匹配驱动版本:
    from webdriver_manager.chrome import ChromeDriverManager
    
    driver = webdriver.Chrome(ChromeDriverManager().install())

7. 扩展思考

本文方案可迁移到其他动态网站如:
– 微博 /Twitter 等社交媒体
– 电商商品评论抓取
– 金融实时数据监控

对于更复杂的场景,建议尝试:
– Playwright 的自动等待特性
– Puppeteer 的请求拦截功能
– 结合 Scrapy 构建分布式爬虫

实际项目中建议根据具体需求组合多种技术,并严格遵守目标网站的 robots.txt 规定。

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