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

Python 2.x实现Power BI报表截图遇元素过期异常求助

解决Power BI登录截图中的Stale Element Reference错误

问题背景

需在Python 2.x环境(适配Power Automate)下编写脚本,完成Power BI报表截图:流程为输入邮箱→提交→输入密码→登录→确认保持登录,最终截取报表画面。当前脚本执行actionChains.click(password_field).send_keys(password).perform()时触发错误:Message: stale element reference: stale element not found。

原代码如下:

import datetime
import time
import os
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.webdriver.common.action_chains import ActionChains
from selenium.common.exceptions import StaleElementReferenceException

def login_powerbi(username, password):
    # Set up the ChromeDriver path in the PATH environment variable
    chromedriver_path = 'C:/Users/Desktop/Screenshot/chrome_driver/chromedriver.exe'
    driver = webdriver.Chrome(executable_path=chromedriver_path)

    # Set up the webdriver
    # driver = webdriver.Chrome()
    actionChains = ActionChains(driver)

    try:
        # Open the Power BI report URL (login page)
        driver.get("https://app.powerbi.com/")

        # Wait for the login page to load
        time.sleep(5)
        wait = WebDriverWait(driver, 60)

        email_field = wait.until(EC.presence_of_element_located((By.ID, "email")))
        actionChains.click(email_field).send_keys(username).perform()
        driver.find_element(By.CSS_SELECTOR, "[id=submitBtn]").click()

        time.sleep(5)
        # Wait for the password field to load and then enter the password
        password_field = wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, "[type=password]")))
        actionChains.click(password_field).send_keys(password).perform()

        # Submit the password form
        driver.find_element(By.CSS_SELECTOR, "[id=idSIButton9]").click()

        # Wait for the "Stay signed in?" prompt to load and then click "Yes"
        time.sleep(3)
        stay_signed_in_prompt = wait.until(EC.presence_of_element_located((By.ID, "idSIButton9")))  # idSIButton9
        stay_signed_in_prompt.click()

        # Wait for the Power BI report to load after authentication
        driver.implicitly_wait(30)

        # Add a delay before taking the screenshot to ensure the report is fully loaded
        time.sleep(10)

        # Take the screenshot
        now = datetime.datetime.now()
        file_name = 'powerBI_{}.png'.format(now.strftime("%Y-%m-%d_%H-%M-%S"))
        output_path = "C:/Users/Desktop/Screenshot/output/"

        screenshot_output_file = os.path.join(output_path, file_name)
        screenshot_BI = driver.save_screenshot(screenshot_output_file)
        print(screenshot_BI)
        print("Screenshot saved as {}".format(screenshot_output_file))

    except StaleElementReferenceException as e:
        # Re-locate the element and retry the action
        print("Stale element reference, retrying...")
        login_powerbi(username, password)

    except Exception as e:
        print("Error during login and screenshot capture: {}".format(e))

    finally:
        # Close the browser
        driver.quit()

if __name__ == "__main__":
    # Replace 'your_username' and 'your_password' with your actual Power BI login credentials
    login_powerbi("your@mail.com", "password")

错误原因

Stale Element Reference错误是因为页面DOM刷新/跳转后,之前定位的元素引用失效。原代码存在以下问题:

  • 复用全局ActionChains实例,页面跳转后实例关联的元素上下文过期
  • 依赖硬编码time.sleep(),无法精准等待元素加载完成,导致定位时机错误
  • 页面跳转后未重新定位元素,直接使用旧引用

修正后的代码

import datetime
import time
import os
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 StaleElementReferenceException

def login_powerbi(username, password, report_url="https://app.powerbi.com/"):
    chromedriver_path = 'C:/Users/Desktop/Screenshot/chrome_driver/chromedriver.exe'
    driver = webdriver.Chrome(executable_path=chromedriver_path)
    wait = WebDriverWait(driver, 60)
    
    try:
        # 打开目标Power BI页面
        driver.get(report_url)
        
        # 输入邮箱并提交
        email_field = wait.until(EC.visibility_of_element_located((By.ID, "email")))
        email_field.clear()
        email_field.send_keys(username)
        submit_btn = wait.until(EC.element_to_be_clickable((By.ID, "submitBtn")))
        submit_btn.click()
        
        # 等待密码页面加载,输入密码
        password_field = wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, "[type=password]")))
        password_field.clear()
        password_field.send_keys(password)
        login_btn = wait.until(EC.element_to_be_clickable((By.ID, "idSIButton9")))
        login_btn.click()
        
        # 处理保持登录提示
        stay_signed_btn = wait.until(EC.element_to_be_clickable((By.ID, "idSIButton9")))
        stay_signed_btn.click()
        
        # 等待报表页面完全加载(需根据实际报表调整选择器)
        wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, ".reportContainer")))
        time.sleep(2)  # 额外等待渲染完成
        
        # 生成截图(确保输出目录存在)
        now = datetime.datetime.now()
        file_name = 'powerBI_{}.png'.format(now.strftime("%Y-%m-%d_%H-%M-%S"))
        output_path = "C:/Users/Desktop/Screenshot/output/"
        if not os.path.exists(output_path):
            os.makedirs(output_path)
        screenshot_output_file = os.path.join(output_path, file_name)
        
        driver.save_screenshot(screenshot_output_file)
        print("截图已保存至: {}".format(screenshot_output_file))

    except StaleElementReferenceException:
        print("元素引用失效,正在重试...")
        driver.quit()
        login_powerbi(username, password, report_url)
    except Exception as e:
        print("执行出错: {}".format(e))
    finally:
        driver.quit()

if __name__ == "__main__":
    # 替换为实际账号密码和目标报表URL
    login_powerbi("your@mail.com", "password", "https://app.powerbi.com/groups/xxx/reports/xxx")

关键修改点

  • 移除全局ActionChains实例,直接使用元素自身的send_keys()和click()方法,避免上下文失效
  • 用显式等待替换大部分time.sleep(),确保元素可交互后再操作
  • 页面跳转后重新定位元素,不复用旧引用
  • 添加目录检查,自动创建截图输出目录
  • 支持传入自定义报表URL,无需固定登录页
  • 调整报表加载等待条件,使用页面特有元素选择器(需根据实际报表修改)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 16:15:00