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

Python中Selenium抓取YouTube链接遇stale element reference错误

修改方案及代码优化

问题分析

  1. Stale Element错误:点击搜索按钮后重复调用driver.get(new_path),导致页面重新加载,后续操作可能引用失效的元素;滚动加载后页面DOM更新,若元素引用未同步更新也会触发该错误。
  2. 链接过滤失效:判断i != "None"逻辑错误,href为空时返回的是Python的None对象而非字符串"None",导致过滤逻辑无法生效。
  3. 元素定位冗余:遍历所有a标签再过滤的方式效率低,可直接定位目标链接减少无效操作。

具体修改点

  • 移除重复跳转:点击搜索按钮后已自动进入搜索结果页,无需再次调用driver.get(new_path)。
  • 修正过滤逻辑:将i != "None"改为i is not None,正确识别空链接。
  • 优化元素定位:用CSS选择器a[href*="watch?v="]直接定位目标视频链接,避免全量遍历。
  • 增加显式等待:滚动后等待页面元素加载完成,避免DOM未更新完全导致的元素获取失败。
  • 增加去重逻辑:避免重复抓取同一视频链接。

修改后的完整代码

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

options = webdriver.ChromeOptions()
options.add_experimental_option("detach", True)
options.add_argument("--disable-extensions")
options.add_argument("--disable-notifications")
options.add_argument("--disable-advertisement")
options.add_argument("--disable-popup-blocking")
options.add_argument("start-maximized")

driver = webdriver.Chrome(options=options)
driver.get("https://youtube.com")

# 等待搜索框加载并定位
search_box = WebDriverWait(driver, 10).until(
    EC.presence_of_element_located((By.CSS_SELECTOR, 'input#search'))
)
search_word = input("Enter the search keyword: ")
search_box.send_keys(search_word)

# 等待搜索按钮加载并点击
search_button = WebDriverWait(driver, 10).until(
    EC.element_to_be_clickable((By.CSS_SELECTOR, 'button#search-icon-legacy'))
)
search_button.click()

SCROLL_PAUSE_TIME = 3
last_height = driver.execute_script("return document.documentElement.scrollHeight")

while True:
    driver.execute_script("window.scrollTo(0, document.documentElement.scrollHeight);")
    time.sleep(SCROLL_PAUSE_TIME)
    new_height = driver.execute_script("return document.documentElement.scrollHeight")
    
    # 等待页面视频链接加载完成
    WebDriverWait(driver, 10).until(
        EC.presence_of_element_located((By.CSS_SELECTOR, 'a[href*="watch?v="]'))
    )
    
    if new_height == last_height:
        break
    last_height = new_height

# 直接获取所有目标视频链接并去重
filtered_links = []
video_links = driver.find_elements(By.CSS_SELECTOR, 'a[href*="watch?v="]')
for link in video_links:
    href = link.get_attribute("href")
    if href is not None and href not in filtered_links:
        filtered_links.append(href)
        print(href)

# 可选:将结果保存到CSV文件
pd.DataFrame({"video_links": filtered_links}).to_csv("youtube_video_links.csv", index=False)

额外说明

  • 用CSS选择器替代全量XPATH,定位更稳定且维护成本更低。
  • 显式等待替代固定sleep,提升脚本对网络延迟的适应性,减少元素加载失败概率。
  • 去重逻辑避免重复存储同一视频链接,优化结果质量。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 11:59:56