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

求助:Python Selenium无法填充Microsoft Report Builder页面日期框

问题解决:Microsoft Report Builder 日期填充自动化失败

核心问题分析

  • 日期逻辑错误:当前代码生成的是当月第一天,而非需求的上月第一天/最后一天
  • 仅修改DOM属性未触发页面事件:Report Viewer的输入框依赖onchange事件同步值到后端,单纯设置value属性不会被页面识别
  • 未等待输入框完全加载:进入AR页面后直接操作元素,可能元素还未渲染完成
  • 使用了Selenium已废弃的API:find_element_by_xpath在新版本中已被弃用

修正后的完整代码

import time
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from datetime import datetime, timedelta

def open_and_click_button(url, username, password):
    driver = None
    try:
        # 初始化Chrome浏览器(可根据需要调整headless模式)
        options = Options()
        options.headless = True
        driver = webdriver.Chrome(options=options)
        driver.get(url)
        
        # 登录流程
        username_field = WebDriverWait(driver, 10).until(
            EC.visibility_of_element_located((By.ID, 'mat-input-0'))
        )
        username_field.send_keys(username)
        
        password_field = WebDriverWait(driver, 10).until(
            EC.visibility_of_element_located((By.ID, 'mat-input-1'))
        )
        password_field.send_keys(password)
        
        login_button = driver.find_element(By.CLASS_NAME, 'mat-button-wrapper')
        login_button.click()
        
        # 点击Reports按钮
        reports_button = WebDriverWait(driver, 10).until(
            EC.element_to_be_clickable((By.XPATH, '//img[@alt="Reports" and contains(@src, "appmenu_reports_24.svg")]'))
        )
        driver.execute_script("arguments[0].click();", reports_button)
        
        # 点击AR按钮
        ar_button = WebDriverWait(driver, 10).until(
            EC.element_to_be_clickable((By.XPATH, '/html/body/app-root/div/app-layout/app-header/mat-sidenav-container/mat-sidenav-content/div/app-report-view/div[3]/app-inview-grid/ag-grid-angular/div/div[2]/div[2]/div[3]/div[1]/div/div[2]/div/div/div[4]/div[2]/span/span[4]/app-report-link-renderer/a'))
        )
        driver.execute_script("arguments[0].click();", ar_button)
        
        # ------------------- 日期处理修正 -------------------
        # 获取上月的第一天和最后一天
        today = datetime.today()
        # 计算上月第一天:当月第一天减1天,再取当月第一天
        first_day_last_month = (today.replace(day=1) - timedelta(days=1)).replace(day=1)
        # 计算上月最后一天:当月第一天减1天
        last_day_last_month = today.replace(day=1) - timedelta(days=1)
        
        # 格式化日期为YYYY-MM-DD
        start_date = first_day_last_month.strftime("%Y-%m-%d")
        end_date = last_day_last_month.strftime("%Y-%m-%d")
        
        # ------------------- 填充开始日期 -------------------
        # 等待开始日期输入框可交互
        start_date_input = WebDriverWait(driver, 15).until(
            EC.element_to_be_clickable((By.ID, 'ReportViewerControl_ctl04_ctl03_txtValue'))
        )
        # 清除原有内容(如果有)
        start_date_input.clear()
        # 输入日期
        start_date_input.send_keys(start_date)
        # 触发onchange事件,确保页面识别到值变化
        driver.execute_script("arguments[0].dispatchEvent(new Event('change'));", start_date_input)
        
        # ------------------- 填充结束日期(需根据实际ID调整) -------------------
        # 请替换为实际结束日期框的ID
        end_date_input = WebDriverWait(driver, 15).until(
            EC.element_to_be_clickable((By.ID, 'ReportViewerControl_ctl04_ctl05_txtValue'))
        )
        end_date_input.clear()
        end_date_input.send_keys(end_date)
        driver.execute_script("arguments[0].dispatchEvent(new Event('change'));", end_date_input)
        
        # ------------------- 后续操作:取消下拉框选项、下载报告(示例) -------------------
        # 若下拉框为标准select元素,可使用以下代码
        # from selenium.webdriver.support.ui import Select
        # dropdown = Select(driver.find_element(By.ID, '目标下拉框ID'))
        # dropdown.deselect_by_value('要取消的选项值')
        # 点击下载按钮示例
        # download_btn = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, '下载按钮的XPath')))
        # download_btn.click()
        
    except Exception as e:
        print(f"错误信息: {e}")
        # 可选:保存错误截图用于排查
        # if driver:
        #     driver.save_screenshot('error_screenshot.png')
    finally:
        if driver:
            time.sleep(10)
            driver.quit()

# 示例调用
url = "X"
username = "X"
password = "X"
open_and_click_button(url, username, password)

关键改进点说明

  1. 日期逻辑修正:
    • 通过datetime和timedelta精准计算上月的第一天和最后一天,完全匹配需求
  2. 元素交互优化:
    • 等待输入框进入可交互状态(而非仅可见),避免因元素未加载完成导致操作失败
    • 先清空输入框再填入日期,避免原有内容干扰
    • 触发change事件:通过JS模拟输入框的onchange行为,让Report Viewer后端同步日期值(这是原代码失效的核心原因)
  3. API更新:
    • 替换已废弃的find_element_by_xpath为标准的WebDriverWait + By.ID写法,适配新版Selenium
  4. 鲁棒性提升:
    • 优化driver生命周期管理,确保异常情况下浏览器能正常关闭
    • 增加错误截图注释,方便问题排查

注意事项

  • 结束日期框的ID需要根据实际页面元素调整(Report Viewer的日期控件ID通常有规律,比如开始为ctl03,结束为ctl05)
  • 如果日期输入框是弹出日历控件,需先点击输入框唤起日历再选择日期;根据提供的元素代码,直接输入文本是可行的
  • 下拉框操作需根据实际元素类型(标准select或自定义下拉)调整代码,注释中提供了标准Select类的使用示例

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 08:32:38