(蟒蛇)带有 ASP.NET 报表查看器的 Selenium:使用 WebDriverWait 进行显式等待的单击不起作用

(Python) Selenium with ASP.NET report viewer: Click with explicit wait with WebDriverWait doesn't work

提问人:Mark 提问时间:8/12/2023 最后编辑:Mark 更新时间:8/14/2023 访问量:53

问:

我正在尝试通过selenium从我们公司的 ASP.NET ReportViewer中提取CSV报告,但它不适用于显式等待。

我的脚本填写了一些文本字段,然后单击“生成报告”按钮。 单击该按钮后,将显示报告,并出现一个附加工具栏,您可以在其中单击菜单按钮 (ReportViewerControl_ctl05_ctl04_ctl00_ButtonLink) 并选择文件格式以下载报告。

设置:

options = Options()
service = Service("chromedriver.exe")
driver = webdriver.Chrome(service=service, options=options)
driver.get("ASP.NET Report Website")

工作方案:

time.sleep(2)
menu = driver.find_element('xpath','//*[@id="ReportViewerControl_ctl05_ctl04_ctl00_ButtonLink"]')
menu.click()
csv = driver.find_element('xpath',"//a[contains(@title, 'CSV')]")
driver.execute_script("arguments[0].click();", csv)

它做了几个测试,试图通过显式等待来完成点击:

第一种使用“visibility_of_element_located”的方法

WebDriverWait(driver, 10).until(EC.visibility_of_element_located(('xpath','//*[@id="ReportViewerControl_ctl05_ctl04_ctl00_ButtonLink"]')))
menu = driver.find_element('xpath','//*[@id="ReportViewerControl_ctl05_ctl04_ctl00_ButtonLink"]')
menu.click()

结果:什么也没发生,也没有错误

使用“presence_of_element_located”的第二种方法

WebDriverWait(driver, 10).until(EC.presence_of_element_located(('xpath','//*[@id="ReportViewerControl_ctl05_ctl04_ctl00_ButtonLink"]')))
menu = driver.find_element('xpath','//*[@id="ReportViewerControl_ctl05_ctl04_ctl00_ButtonLink"]')
menu.click()   

结果:什么也没发生,也没有错误

第三种方法与“presence_of_element_located”

WebDriverWait(driver, 10).until(EC.element_to_be_clickable(('xpath','//*[@id="ReportViewerControl_ctl05_ctl04_ctl00_ButtonLink"]')))
menu = driver.find_element('xpath','//*[@id="ReportViewerControl_ctl05_ctl04_ctl00_ButtonLink"]')
menu.click()    

结果:什么也没发生,也没有错误

因此,等到显示菜单/按钮是有效的并且不会引发错误,但我不明白为什么 .click() 不起作用。

编辑 13.08
一个可行的解决方案似乎是等到VisibleReportContentReportViewerControl_ctl09有了孩子。此 dv 包含报告。

/html/body/form[@id='ReportViewerForm']/span[@id='ReportViewerControl_ReportViewer']/div[@id='ReportViewerControl']/table[@id='ReportViewerControl_fixedTable']/tbody/tr[5]/td[3]/div[@id='ReportViewerControl_ctl09']/div[@id='VisibleReportContentReportViewerControl_ctl09']/*
WebDriverWait(driver, 10, poll_frequency=0.1).until(EC.visibility_of_element_located(('xpath',"/html/body/form[@id='ReportViewerForm']/span[@id='ReportViewerControl_ReportViewer']/div[@id='ReportViewerControl']/table[@id='ReportViewerControl_fixedTable']/tbody/tr[5]/td[3]/div[@id='ReportViewerControl_ctl09']/div[@id='VisibleReportContentReportViewerControl_ctl09']/*")))

但这只是第一份报告的解决方案。我想生成多个报告,因此我不重新加载页面(重新加载需要 4-5 秒)。下一个 childelement 会随着每个新报表更改其 id:

/html/body/form[@id='ReportViewerForm']/span[@id='ReportViewerControl_ReportViewer']/div[@id='ReportViewerControl']/table[@id='ReportViewerControl_fixedTable']/tbody/tr[5]/td[3]/div[@id='ReportViewerControl_ctl09']/div[@id='VisibleReportContentReportViewerControl_ctl09']/div[@id='Pecd2ee77db264acb9b0283d9b3fde149_1_oReportDiv']

解决方案(可能不是最好的): 我实现了一个逻辑,该逻辑会等到第一个报告有一个子元素,然后存储第一个子函数的 id,并在下一个循环中等待,直到 id 发生更改。

python asp.net selenium-webdriver webdriverwait reportviewer

评论

0赞 undetected Selenium 8/13/2023
使用工具栏的 HTML 更新问题,并在报表准备就绪之前和报表准备就绪后显示菜单按钮。

答: 暂无答案