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

Python实现Power BI报表定时截图:解决元素不可交互报错

Power BI报表自动截图脚本问题及解决方案

需求

  • 通过Python实现Power BI报表截图,需完成「输入邮箱→提交」「输入密码→登录」「保持登录→确认」的完整登录流程
  • 脚本需适配Databricks环境,支持每日定时自动运行

原实现代码

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


def login_powerbi(username, password):
    # Set up the ChromeDriver path in the PATH environment variable
    chromedriver_path = 'C:/Users/Desktop/chrome_driver/chromedriver.exe'
    os.environ["PATH"] += os.pathsep + chromedriver_path

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

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

        # Wait for the login page to load
        wait = WebDriverWait(driver, 10)
        email_field = wait.until(EC.presence_of_element_located((By.ID, "email")))
        email_field.send_keys(username)

        # Submit the email form
        email_form = driver.find_element_by_id("i0116")
        email_form.submit()

        # Wait for the password field to load and then enter the password
        password_field = wait.until(EC.presence_of_element_located((By.ID, "i0118"))) #i0118
        password_field.send_keys(password)

        # Submit the password form
        password_form = driver.find_element_by_id("i0118") #idSIButton9
        password_form.submit()

        # Wait for the "Stay signed in?" prompt to load and then click "Yes"
        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 = f'screenshot_{now.strftime("%Y-%m-%d_%H-%M-%S")}.png'
        output_path = "C:/Users/Desktop/Screenshot/output/"

        screenshot_output_file = f'{output_path}/{file_name}'
        driver.save_screenshot(screenshot_output_file)

        print(f"Screenshot saved as {screenshot_output_file}")

    except Exception as e:
        print(f"Error during login and screenshot capture: {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_username", "your_password")

报错信息

Error during login and screenshot capture: Message: element not interactable
  (Session info: chrome=115.0.5790.110)
Stacktrace:
Backtrace:
        GetHandleVerifier [0x0063A813+48355]
        (No symbol) [0x005CC4B1]
        (No symbol) [0x004D5220]
        (No symbol) [0x004FD046]
        (No symbol) [0x004FC8B1]
        (No symbol) [0x0051A73C]
        (No symbol) [0x004F9A36]
        (No symbol) [0x0051AA94]
        (No symbol) [0x0052C922]
        (No symbol) [0x0051A536]
        (No symbol) [0x004F82DC]
        (No symbol) [0x004F93DD]
        GetHandleVerifier [0x0089AABD+2539405]
        GetHandleVerifier [0x008DA78F+2800735]
        GetHandleVerifier [0x008D456C+2775612]
        GetHandleVerifier [0x006C51E0+616112]
        (No symbol) [0x005D5F8C]
        (No symbol) [0x005D2328]
        (No symbol) [0x005D240B]
        (No symbol) [0x005C4FF7]
        (No symbol) [0x76FE00C9]
        RtlGetAppContainerNamedObjectPath [0x77587B1E+286]
        RtlGetAppContainerNamedObjectPath [0x77587AEE+238]

[ERROR:ssl_client_socket_impl.cc(980)] handshake failed; returned -1, SSL error code 1, net_error -3

问题分析

  1. element not interactable错误:原代码仅检查元素是否存在,未确认元素可交互;且提交密码时错误使用密码框ID执行提交操作,而非登录按钮。
  2. 环境适配问题:硬编码Windows本地路径,不适用于Databricks的Linux环境;未配置Chrome无头模式,Databricks无桌面环境无法运行普通Chrome实例。
  3. 版本匹配问题:SSL握手错误源于Chrome浏览器与ChromeDriver版本不匹配。

修正后的适配Databricks的代码

import datetime
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.chrome.options import Options
from webdriver_manager.chrome import ChromeDriverManager

def login_powerbi(username, password, powerbi_url):
    # 配置Chrome选项,适配Databricks无头环境
    chrome_options = Options()
    chrome_options.add_argument("--headless=new")  # 无头模式
    chrome_options.add_argument("--no-sandbox")    # 禁用沙箱,适配Linux环境
    chrome_options.add_argument("--disable-dev-shm-usage") # 避免内存不足问题
    chrome_options.add_argument("--disable-gpu")   # 禁用GPU
    chrome_options.add_argument("--start-maximized") # 最大化窗口,确保报表完整截图
    chrome_options.add_argument("--ignore-certificate-errors") # 忽略SSL证书错误

    # 使用webdriver-manager自动安装对应版本的ChromeDriver
    driver = webdriver.Chrome(
        executable_path=ChromeDriverManager().install(),
        options=chrome_options
    )

    wait = WebDriverWait(driver, 20) # 延长等待时间,适配Power BI加载速度

    try:
        # 打开Power BI报表链接
        driver.get(powerbi_url)

        # 输入邮箱并提交
        email_field = wait.until(EC.element_to_be_clickable((By.ID, "i0116")))
        email_field.send_keys(username)
        submit_email_btn = wait.until(EC.element_to_be_clickable((By.ID, "idSIButton9")))
        submit_email_btn.click()

        # 输入密码并提交
        password_field = wait.until(EC.element_to_be_clickable((By.ID, "i0118")))
        password_field.send_keys(password)
        submit_password_btn = wait.until(EC.element_to_be_clickable((By.ID, "idSIButton9")))
        submit_password_btn.click()

        # 确认保持登录
        stay_signed_in_btn = wait.until(EC.element_to_be_clickable((By.ID, "idSIButton9")))
        stay_signed_in_btn.click()

        # 等待报表完全加载:等待报表核心元素出现
        wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, ".visualContainerHost")))

        # 截图保存到DBFS路径(Databricks可访问的存储)
        now = datetime.datetime.now()
        file_name = f'screenshot_{now.strftime("%Y-%m-%d_%H-%M-%S")}.png'
        # 确保DBFS目录存在
        output_path = "/dbfs/mnt/powerbi_screenshots/"
        os.makedirs(output_path, exist_ok=True)
        screenshot_path = os.path.join(output_path, file_name)

        driver.save_screenshot(screenshot_path)
        print(f"截图已保存至:{screenshot_path}")

    except Exception as e:
        print(f"登录或截图过程出错:{str(e)}")
        # 可选:保存错误截图用于排查
        error_screenshot_path = f"/dbfs/mnt/powerbi_screenshots/error_{now.strftime('%Y-%m-%d_%H-%M-%S')}.png"
        driver.save_screenshot(error_screenshot_path)
        print(f"错误状态截图已保存至:{error_screenshot_path}")
    finally:
        driver.quit()

if __name__ == "__main__":
    # 替换为实际的Power BI URL、用户名和密码(建议用Databricks Secrets管理敏感信息)
    POWERBI_URL = "https://app.powerbi.com/groups/xxx/reports/xxx/ReportSection"
    USERNAME = "your_email@domain.com"
    PASSWORD = "your_password"
    login_powerbi(USERNAME, PASSWORD, POWERBI_URL)

关键修正说明

  • 自动管理Driver版本:使用webdriver-manager自动下载匹配当前Chrome版本的Driver,解决SSL握手和版本不匹配问题。
  • 适配Databricks环境:配置无头模式、禁用沙箱等参数,确保在无桌面的Linux环境下运行。
  • 可靠的元素等待:改用element_to_be_clickable等待元素可交互,避免元素未加载完成就操作。
  • 正确的元素定位:修正提交按钮的定位,使用正确的登录按钮ID执行点击,而非密码框。
  • DBFS路径存储:将截图保存到Databricks的DBFS路径,确保脚本运行后可访问截图文件。
  • 敏感信息管理:建议使用Databricks Secrets存储用户名和密码,避免硬编码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 02:22:07