Selenium [Python绑定,Chrome驱动程序]:完全禁用超时

时间:2018-03-14 11:17:23

标签: python google-chrome selenium

我们有一个Selenium流程,可以从我们的数据提供者处获取数据以进行进一步处理。该过程试图获取所有历史数据,并且由于我们没有可靠地过滤掉最近编辑过的数据的功能,因此我们必须不时获得完整的数据转储以确保不丢弃任何记录。

Selenium进程是作为Python脚本编写的。它进入特定网站,登录,按下触发报告生成的按钮,然后下载报告。问题是,对于完整转储报告,报告生成开始花费的时间超过默认的Selenium超时。

我们使用Google Chrome驱动程序,但如果其他驱动程序能够完全禁用超时,则会愿意更改浏览器/驱动程序。

以下是代码的简化版本,其中只包含适当描述此问题所需的简单内容。标记超出报告超时的位置。点击按钮后,它正在等待网站的回复。如何禁用它,为什么我们目前所做的事情(可以在下面看到)是不够的?

from selenium import webdriver

def selectPopUp(driver, main_window_handle, maxWait=100):
    """
    Selects a pop-up window. If no pop-up window appears, raises an
    Exception.

    :param maxWait: how long to wait (in seconds) before raising the error?
    """

    popup_window_handle = None
    i = 0

    while (not popup_window_handle) and (i < maxWait):

        for handle in driver.window_handles:

            if handle != main_window_handle:
                popup_window_handle = handle
                break

        # Wait a litle and re-iterate.
        time.sleep(1)
        i += 1

    if popup_window_handle != None:
        driver.switch_to.window(popup_window_handle)
        return popup_window_handle
    else:
        raise Exception("No pop-up window appeared although the program was expecting one.")

def selectOption(dropdown, option, possibilities):
    """
    Validates and selects an option from a drop-down.

    :param dropdown: the Selenium reference to the dropdown selection.
    :param option: the name of the option we'll select
    :param possibilities: the possibilities we allow to choose from --
                          will raise an Exception
                          if `option` is not in `possibilities`.
    :returns: Selenium selection.
    """

    # Select the default Excel option
    if option in possibilities:
        return dropdown.find_element_by_xpath("//option[@value='" + option + "']")\
                       .click()
    else:
        raise Exception("Invalid choice! Use one of the following: \n\n   " + \
                        "\n   ".join(possibilities))


chromeOptions = webdriver.ChromeOptions()
prefs = {"download.default_directory" : DOWNLOAD_DIRECTORY}
chromeOptions.add_experimental_option("prefs", prefs)
driver = webdriver.Chrome(executable_path=settings.chromeDriver, 
                          chrome_options=chromeOptions)

# Set an infite timeout time so that the slow Crystal reports
# would stand a chance of not timing out too.
driver.set_page_load_timeout(9999999999)
driver.set_script_timeout(9999999999)

# We go to the relevant website - that part is edited out.
# Once in the website, we select the current window handle
# to be able to come back to it after navigating through pop-ups.
main_window_handle = driver.current_window_handle

reportDropDown = driver.find_element_by_id(REPORT_ELEMENT_ID)
selectedReport = reportDropDown.find_element_by_xpath("//option[@value='" + SELCTED_REPORT_TITLE + "']")
selectedReport.click()

########################################################################
# >>>>>>>> The first place where the process keeps timing out. <<<<<<< #
########################################################################

# Click on the export button to open export pop-up.
exportButton = driver.find_element_by_name(r'crytlViewer$ctl02$ctl00')
exportButton.click()

# Now a pop-up with a download button appears. Select it.
popUpHandle = selectPopUp(driver, main_window_handle)

# Now, select a particular download format.
formatDropDown = driver.find_element_by_id("exportFormatList")
selectedFormat = selectOption(formatDropDown, reportFormat, REPORT_FORMAT_LIST)

# Download the report.
driver.find_element_by_id("submitexport").click()


#########################################################################
# >>>>>>>> The second place where the process keeps timing out. <<<<<<< #
#########################################################################

我们得到的错误消息的代表示例如下:

    Traceback (most recent call last):
    File "/home/ubuntu/main/oodle/core/utils.py", line 296, in repeatUntilSuccess
    return func()
    File "/home/ubuntu/main/oodle/salesforce/data_feed.py", line 277, in <lambda>
    cleanUp=True),
    File "/home/ubuntu/main/oodle/salesforce/data_feed.py", line 322, in pushReports
    'liveEnvironment': self.liveEnvironment}]\
    File "/home/ubuntu/main/oodle/core/reporting.py", line 1160, in __getitem__
    self.handlers[name].PreparePandas(**paramDict)
    File "/home/ubuntu/main/oodle/reports/vienna_salesforce_data_feed/Salesforce_LoanObject_Parsed.py", line 38, in PreparePandas
    loan = self.manager.handlers[crystalReport].PreparePandas()
    File "/home/ubuntu/main/oodle/core/reporting.py", line 1231, in PreparePandas
    return self.TransformRaw(self.GetRaw(fileFrom))
    File "/home/ubuntu/main/oodle/core/reporting.py", line 1387, in GetRaw
    self.PrepareExcel(fileFrom)
    File "/home/ubuntu/main/oodle/core/reporting.py", line 1367, in PrepareExcel
    fileTo=fileTo)
    File "/home/ubuntu/main/oodle/vienna/crystal.py", line 293, in downloadReport
    self.downloadReport_no_error_handling(reportTitle, reportFormat, fileTo)
    File "/home/ubuntu/main/oodle/vienna/crystal.py", line 247, in downloadReport_no_error_handling
    self.driver.find_element_by_id("submitexport").click()
    File "/home/ubuntu/.local/lib/python2.7/site-packages/selenium/webdriver/remote/webelement.py", line 77, in click
    self._execute(Command.CLICK_ELEMENT)
    File "/home/ubuntu/.local/lib/python2.7/site-packages/selenium/webdriver/remote/webelement.py", line 493, in _execute
    return self._parent.execute(command, params)
    File "/home/ubuntu/.local/lib/python2.7/site-packages/selenium/webdriver/remote/webdriver.py", line 256, in execute
    self.error_handler.check_response(response)
    File "/home/ubuntu/.local/lib/python2.7/site-packages/selenium/webdriver/remote/errorhandler.py", line 194, in check_response
    raise exception_class(message, screen, stacktrace)
    TimeoutException: Message: timeout
    (Session info: chrome=60.0.3112.78)
    (Driver info: chromedriver=2.29.461571 (8a88bbe0775e2a23afda0ceaf2ef7ee74e822cc5),platform=Linux 4.4.0-1052-aws x86_64)

在Alexey Dolgopolov建议的编辑后,我们收到以下错误消息,与前一个略有不同:

  Traceback (most recent call last):
  File "/home/ubuntu/main/oodle/core/utils.py", line 296, in repeatUntilSuccess
  return func()
  File "/home/ubuntu/main/oodle/salesforce/data_feed.py", line 277, in <lambda>
  cleanUp=True),
  File "/home/ubuntu/main/oodle/salesforce/data_feed.py", line 322, in pushReports
  'liveEnvironment': self.liveEnvironment}]\
  File "/home/ubuntu/main/oodle/core/reporting.py", line 1160, in __getitem__
  self.handlers[name].PreparePandas(**paramDict)
  File "/home/ubuntu/main/oodle/reports/vienna_salesforce_data_feed/Salesforce_LoanObject_Parsed.py", line 38, in PreparePandas
  loan = self.manager.handlers[crystalReport].PreparePandas()
  File "/home/ubuntu/main/oodle/core/reporting.py", line 1231, in PreparePandas
  return self.TransformRaw(self.GetRaw(fileFrom))
  File "/home/ubuntu/main/oodle/core/reporting.py", line 1387, in GetRaw
  self.PrepareExcel(fileFrom)
  File "/home/ubuntu/main/oodle/core/reporting.py", line 1367, in PrepareExcel
  fileTo=fileTo)
  File "/home/ubuntu/main/oodle/vienna/crystal.py", line 318, in downloadReport
  try:
  File "/home/ubuntu/main/oodle/vienna/crystal.py", line 254, in downloadReport_no_error_handling
  exportButton.click()
  File "/home/ubuntu/.local/lib/python2.7/site-packages/selenium/webdriver/remote/webelement.py", line 77, in click
  self._execute(Command.CLICK_ELEMENT)
  File "/home/ubuntu/.local/lib/python2.7/site-packages/selenium/webdriver/remote/webelement.py", line 494, in _execute
  return self._parent.execute(command, params)
  File "/home/ubuntu/.local/lib/python2.7/site-packages/selenium/webdriver/remote/webdriver.py", line 236, in execute
  self.error_handler.check_response(response)
  File "/home/ubuntu/.local/lib/python2.7/site-packages/selenium/webdriver/remote/errorhandler.py", line 192, in check_response
  raise exception_class(message, screen, stacktrace)
  TimeoutException: Message: timeout
  (Session info: chrome=60.0.3112.78)
  (Driver info: chromedriver=2.29.461571 (8a88bbe0775e2a23afda0ceaf2ef7ee74e822cc5),platform=Linux 4.10.0-26-generic x86_64)

1 个答案:

答案 0 :(得分:0)

find_element_by_<whatever>发生implicitly_wait超时时。默认值为0.

我想,你不需要禁用超时。尝试使用显式等待。阅读http://selenium-python.readthedocs.io/waits.htmlhttps://seleniumhq.github.io/selenium/docs/api/py/webdriver_support/selenium.webdriver.support.wait.html#module-selenium.webdriver.support.wait

使用类似的东西:

from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
...
selectedReport.click()
exportButton = WebDriverWait(driver, 9999, 5).until(
        EC.visibility_of_element_located(
            (By.NAME, r'crytlViewer$ctl02$ctl00')
        )