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

使用Selenium爬取总统候选人信息时遇StaleElementReferenceException错误求解

解决Selenium爬取2024总统候选人信息时的StaleElementReferenceException错误

错误原因

你遇到的StaleElementReferenceException是因为:当你在循环里调用parse_profile函数跳转到候选人个人主页后,初始页面的DOM已经被销毁,之前获取的elems列表里的元素全部失效,循环到下一个元素时就会报错。

修复方案

核心思路是先把所有候选人的姓名和主页URL从初始页面一次性提取出来,存储到本地列表,再遍历这个列表去访问每个候选人的主页,这样就不会依赖已经失效的DOM元素了。同时加入显式等待,避免页面未加载完成就查找元素。

修改后的完整代码

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 selenium.common.exceptions import TimeoutException, NoSuchElementException

driver = webdriver.Chrome()
pres_candidates_url = "https://ballotpedia.org/Presidential_candidates,_2024"
driver.get(pres_candidates_url)

def parse_profile(profile_url):
    driver.get(profile_url)
    wait = WebDriverWait(driver, 10)
    party = "Unknown"
    official_image = "No image found"
    
    # 获取党派信息,加入等待
    try:
        party_elem = wait.until(EC.presence_of_element_located((By.XPATH, "//div[@class='widget-row value-only white']//a")))
        party = party_elem.text
    except (TimeoutException, NoSuchElementException):
        print(f"无法获取{profile_url}的党派信息")
    
    # 获取图片链接,优先找widget里的图片,再找正文里的
    try:
        image_elem = wait.until(EC.presence_of_element_located((By.XPATH, "//div[@class='widget-row']//img")))
        official_image = image_elem.get_attribute("src")
    except (TimeoutException, NoSuchElementException):
        try:
            image_elem = wait.until(EC.presence_of_element_located((By.XPATH, "//div[@class='mw-parser-output']//p//img")))
            official_image = image_elem.get_attribute("src")
        except (TimeoutException, NoSuchElementException):
            print(f"无法获取{profile_url}的图片链接")
    
    metadata = {"Party": party}
    return official_image, metadata

# 先一次性提取所有候选人的姓名和URL,存储到列表
candidates = []
try:
    wait = WebDriverWait(driver, 10)
    elems = wait.until(EC.presence_of_all_elements_located((By.XPATH, "//div[@class='mw-parser-output']//ul//li//b//a")))
    for elem in elems:
        words = elem.text.split()
        count = sum(1 for word in words if word[0].islower())
        if count < 1:
            name = elem.text
            member_url = elem.get_attribute("href")
            candidates.append({"name": name, "url": member_url})
except TimeoutException:
    print("无法加载初始页面的候选人列表")

# 遍历预存的候选人列表,爬取详细信息
all_members = []
for candidate in candidates:
    name = candidate["name"]
    member_url = candidate["url"]
    print(f"正在处理: {name} - {member_url}")
    official_image, metadata = parse_profile(member_url)
    member = {
        "name": name,
        "url": member_url,
        "official_image": official_image,
        "metadata": metadata
    }
    all_members.append(member)
    print(f"完成处理: {name}")

print("\n爬取结果:")
for member in all_members:
    print(member)

driver.quit()

关键修改说明

  1. 预存候选人信息:先从初始页面把所有需要的姓名和URL提取到本地列表,之后循环只操作这个列表,彻底避免了页面跳转后元素失效的问题。
  2. 加入显式等待:使用WebDriverWait配合expected_conditions,确保元素加载完成后再进行操作,减少因页面加载慢导致的查找失败。
  3. 增强异常处理:给每个元素查找都添加了异常捕获,避免单个候选人的信息爬取失败导致整个程序崩溃。
  4. 优化变量命名:把原代码里的metadata键名从Party:改成Party,更符合常规字典键的命名规范。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 08:12:46