如何优化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()
代码说明
- 集合去重:用
set存储链接,自动避免重复抓取同一链接 - 动态等待:使用
WebDriverWait等待元素加载,比固定sleep更高效且稳定 - 原生滚动:用
driver.execute_script执行JS滚动,比pyautogui更适合浏览器自动化 - 实时统计:滚动过程中实时更新已收集的链接数量,方便监控进度
- 异常处理:对弹窗、加载超时等情况做了异常处理,提升脚本健壮性
内容的提问来源于stack exchange,提问作者Demonslayer
相关产品推荐
相关产品推荐

