You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何优化Python+Selenium爬取Reddit已保存内容的效率?

爬取Reddit已保存内容的效率优化方案

问题现状

使用Python+Selenium爬取Reddit个人账号已保存内容时遇到以下问题:

  • 滚动加载1000条内容耗时约41分钟,效率极低
  • 后续提取链接写入文件速度慢,且动态加载导致旧内容被页面隐藏,无法一次性获取全部链接

优化方案

核心思路:滚动加载时实时提取并保存链接

每次滚动后立即抓取当前页面的新链接,存入集合(自动去重),避免等待全部加载完成后再统一提取,同时解决旧内容被隐藏的问题。

具体优化点

  • 替换pyautogui.scroll为Selenium原生的滚动方法,更稳定且减少依赖
  • 去掉固定时长的sleep,改用WebDriverWait等待元素加载,动态调整等待时间
  • 滚动过程中实时提取链接,存入集合避免重复
  • 使用更稳定的CSS选择器定位元素,减少硬编码XPATH的维护成本
  • 最后批量写入文件,减少IO操作次数

修改后的代码

from time import sleep
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

# 配置参数
login_url = "https://www.reddit.com/login/"
saved_url = "https://www.reddit.com/user/你的用户名/saved"  # 替换为你的用户名
username = "你的账号"
password = "你的密码"
wait_timeout = 10  # 等待元素加载的超时时间
saved_links = set()  # 用集合存储链接,自动去重

# 初始化浏览器
driver = webdriver.Chrome()
driver.maximize_window()
wait = WebDriverWait(driver, wait_timeout)

# 登录流程
driver.get(login_url)
# 等待用户名输入框加载
username_field = wait.until(EC.presence_of_element_located((By.ID, "loginUsername")))
password_field = wait.until(EC.presence_of_element_located((By.ID, "loginPassword")))

username_field.send_keys(username)
password_field.send_keys(password)

# 点击登录按钮
login_btn = wait.until(EC.element_to_be_clickable((By.XPATH, '//button[@type="submit"]')))
login_btn.click()

# 等待跳转至已保存页面
wait.until(EC.url_changes(login_url))
driver.get(saved_url)

# 关闭弹窗(如果存在)
try:
    close_btn = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button[aria-label='Close']")))
    close_btn.click()
except:
    pass  # 没有弹窗则跳过

# 滚动加载并实时提取链接
last_height = driver.execute_script("return document.body.scrollHeight")
loaded_count = 0
target_count = 1000  # 目标加载数量

while loaded_count < target_count:
    # 提取当前页面的所有评论链接
    current_links = driver.find_elements(By.CSS_SELECTOR, "a[href*='/comments/']")
    for link in current_links:
        href = link.get_attribute("href")
        if href and href not in saved_links:
            saved_links.add(href)
            loaded_count = len(saved_links)
            print(f"已收集 {loaded_count} 条链接")
    
    # 滚动到底部
    driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
    
    # 等待新内容加载,或者超时则退出
    try:
        wait.until(lambda d: d.execute_script("return document.body.scrollHeight") > last_height)
        last_height = driver.execute_script("return document.body.scrollHeight")
        sleep(1)  # 短等待确保内容渲染完成
    except:
        print("没有更多内容加载,提前退出")
        break

# 批量写入文件
with open(r"D:\python\links.txt", "w+", encoding="utf-8") as file:
    for link in saved_links:
        file.write(link + "\n")

print(f"任务完成,共保存 {len(saved_links)} 条链接")
driver.quit()

代码说明

  1. 集合去重:用set存储链接,自动避免重复抓取同一链接
  2. 动态等待:使用WebDriverWait等待元素加载,比固定sleep更高效且稳定
  3. 原生滚动:用driver.execute_script执行JS滚动,比pyautogui更适合浏览器自动化
  4. 实时统计:滚动过程中实时更新已收集的链接数量,方便监控进度
  5. 异常处理:对弹窗、加载超时等情况做了异常处理,提升脚本健壮性

内容的提问来源于stack exchange,提问作者Demonslayer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 14:33:19