如果在Python中找不到使用selenium的元素,请继续脚本

时间:2016-04-08 15:37:37

标签: python selenium

如果在Python中找不到使用selenium的元素,我在试图弄清楚如何继续脚本时遇到了麻烦。

此代码循环显示报告,找到刷新按钮,然后单击下载按钮。唯一的问题是,某些报告没有刷新按钮。所以,如果找不到按钮,我希望脚本继续。

我仍然是python / selenium的新手,所以这就是我发布整个代码的原因。我需要知道要做些什么才能完成这项工作!提前感谢您对这个头部撞击问题的帮助

这是selenium尝试点击刷新按钮的地方

browser.find_element_by_css_selector("#ctl00_PlaceHolderMain_ReportViewer1_HtmlOutputReportResults2_updateFilters_TitleAnchor").click()

完整的代码:

import time
import os
import os.path
import glob
import shutil
from selenium.webdriver.common.action_chains import ActionChains
from selenium.common.exceptions import MoveTargetOutOfBoundsException
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.common.exceptions import NoSuchElementException
from selenium.common.exceptions import NoAlertPresentException

files = glob.glob('/Users/me/Desktop/AUTOREPORTS/*')
for f in files:
    os.remove(f)        

open('/Users/me/Desktop/AUTOREPORTS/report.csv', "w")

for x in range(1, 73):      
    while True:    
        try:
            fp = webdriver.FirefoxProfile('C:/Users/me/Documents/FirefoxProfile')
            browser = webdriver.Firefox(fp)
            browser.get('https://websitething.com/')

            time.sleep(8)

            browser.find_element_by_id("ctl00_PlaceHolderMain_login_UserName").clear()
            browser.find_element_by_id("ctl00_PlaceHolderMain_login_UserName").send_keys("usr")
            browser.find_element_by_id("ctl00_PlaceHolderMain_login_password").clear()
            browser.find_element_by_id("ctl00_PlaceHolderMain_login_password").send_keys("paswd")
            browser.find_element_by_id("ctl00_PlaceHolderMain_login_login").click()

#gets user to reporting front end

            ReportMgr= browser.find_element_by_partial_link_text('Report Manager')
            ReportMgr.click()

            time.sleep(5)

            CustomReport= browser.find_element_by_partial_link_text('Custom Report')
            CustomReport.click()

            time.sleep(5)

            ProgramManagement= browser.find_element_by_partial_link_text('Program Management')
            ProgramManagement.click()
            ProgramManagement= browser.find_element_by_partial_link_text('Program Management').send_keys(Keys.ARROW_LEFT)

#pulls reports

            browser.find_element_by_partial_link_text('Program Management').click()
            time.sleep(60)
            browser.find_element_by_partial_link_text('Program Management').send_keys(Keys.ARROW_DOWN * x, Keys.ENTER)
            time.sleep(60)
            browser.find_element_by_css_selector("#ctl00_PlaceHolderMain_ReportViewer1_HtmlOutputReportResults2_updateFilters_TitleAnchor").click()            
            time.sleep(60)            
            browser.find_element_by_css_selector("#ctl00_PlaceHolderMain_ReportViewer1_HtmlOutputReportResults2_CSVButton_ImageAnchor > img").click()
            fname = "Report(%s).csv" % (x)
            os.chdir('/Users/me/Desktop/AUTOREPORTS')
            time.sleep(60)
            #browser.find_element_by_partial_link_text('Program Management').click()
            #time.sleep(30)
            browser.quit()

        except:
               browser.quit()           
               continue
        else:
               break

3 个答案:

答案 0 :(得分:1)

使用try / except block to handle the exception并继续。

try:
    browser.find_element_by_css_selector("#ctl00_PlaceHolderMain_ReportViewer1_HtmlOutputReportResults2_updateFilters_TitleAnchor").click()
except NoSuchElementException:
    # do stuff

请注意,Florent B。的回答会在页面上找到多个元素,而不是一个。因此,根据您需要查找的内容以及有多少内容,可能会导致轻微的性能问题。如果你真的需要找到多个元素,他的解决方案就可以正常工作了,但对于OP的问题,最佳实践要求我们使用设计用于处理手头任务的方法而不是设计用于处理多个元素的方法。任务。它就像贪婪的匹配和与正则表达式的懒惰匹配。如果你只需要第一场比赛,那么写一个懒惰的模式会更有效率,即使编写贪婪模式仍然在技术上有效。

答案 1 :(得分:1)

众所周知,只要元素不可用,它就会抛出异常。在这种情况下,我们知道元素有时不可用,所以我们需要处理这个异常。

在Java中,我们可以使用try / catch来处理它。

 try{
    driver.findElement(By.xpath(".//*[@id='menu-item-92']/a")).click(); //your element here
    }catch(Exception e){
        System.out.println(e.getMessage()); //printing exception
    }

请注意:如果要显示这个元素但是没有,那么当我们处理异常时,仍然会执行到下一行。

谢谢你, 穆拉利

答案 2 :(得分:0)

您可以检查find_elements是否返回了至少一个项目:

elements = driver.find_elements_by_css_selector("...")
if elements :
  elements[0].click()

如果你担心它比try / catch更贵,那么它不是,所以这两种方法都是有效的。

Chrome 49.0.2623 Windows 8.1(1000个样本):

        | find_element | find_elements |
Sum     | 10077.4544ms |  9895.2903ms  | diff: -182.1641ms
Mean    |    10.0775ms |     9.8953ms  | diff:  -0.1822ms
Mediam  |     9.7563ms |     9.5361ms  | diff:  -0.2202ms
Min     |     9.0264ms |     9.0220ms  | diff:  -0.0044ms
Std     |     2.2050ms |     2.4411ms  |

Firefox 44.0.2 Windows 8.1(1000个样本):

        | find_element | find_elements |
Sum     |  9146.3389ms |  8860.2409ms  | diff: -286.0981ms
Mean    |     9.1463ms |     8.8602ms  | diff:  -0.2861ms
Mediam  |     8.0231ms |     7.8351ms  | diff:  -0.1880ms
Min     |     6.3442ms |     6.1565ms  | diff:  -0.1877ms
Std     |     5.3030ms |     6.2566ms  |

比较find_element与find_elements的代码:

from selenium import webdriver
from statistics import mode, mean, pstdev, median
import time

driver = webdriver.Chrome()
driver.get("http://stackoverflow.com")
time.sleep(1)

selectors = [
  '#nav-questions',         # present
  '#abcdef',                # not present
  'div.nav:nth-child(2)',   # present
  'div.nav:nth-child(10)',  # not present
  '.youarehere',            # present
  '.abcdef'                 # not present
];

timesA = []
timesB = []

samples = 1000
for i in range(samples):

  start = time.clock()
  try:
    element = driver.find_element_by_css_selector(selectors[i % 6])
  except:
    pass
  timesA.append((time.clock()-start) * 1000.0)

  start = time.clock()
  elements = driver.find_elements_by_css_selector(selectors[i % 6])
  if not elements :
    pass
  timesB.append((time.clock()-start) * 1000.0)

print("\n".join([
  "        | find_element vs find_elements",
  "Sum     | {:10.4f}ms | {:10.4f}ms | diff: {:10.4f}ms".format(sum(timesA), sum(timesB), sum(timesB)-sum(timesA)),
  "Mean    | {:10.4f}ms | {:10.4f}ms | diff: {:10.4f}ms".format(mean(timesA), mean(timesB), mean(timesB)-mean(timesA)),
  "Mediam  | {:10.4f}ms | {:10.4f}ms | diff: {:10.4f}ms".format(median(timesA), median(timesB), median(timesB)-median(timesA)),
  "Min     | {:10.4f}ms | {:10.4f}ms | diff: {:10.4f}ms".format(min(timesA), min(timesB), min(timesB)-min(timesA)),
  "Std     | {:10.4f}ms | {:10.4f}ms |                 ".format(pstdev(timesA), pstdev(timesB))
]))