python - 使用 Selenium 和 Python 迭代 Accordion block 中的每个项目

标签 python selenium boto

我有一个 Accordion block ,我想单击每个项目并截取屏幕截图。每个项目共享一个类,因此我认为 for 循环可以工作,但我无法让它选择项目。

HTML 结构:

<div class="accordionContainer">
    <div class="accordion">
      <h3>Click This</h3>
      <div class="accordionContent" style="display:none">
      </div>
    <div>
    <div class="accordion">
      <h3>Click This</h3>
      <div class="accordionContent" style="display:none">
      </div>
    <div>
</div>

Python:

detailsAccordion = browser.find_elements_by_class_name('accordion')
index = 1
for option in detailsAccordion:
    option.click()
    try:
        element = ui.WebDriverWait(ff, 10).until(lambda driver : driver.find_element_by_xpath("//div[@class='accordion'][" + str(index) + "]/div[@class='accordionContent']").text != "" )
    except:
        print "Can't do it"
        browser.quit()
    index = index + 1
    n = nextNumber(n)
    browser.save_screenshot('{0}\{1}.png'.format(imagesPath, n))
    option.click()

这会导致超时并出现以下错误。我已经查看了此错误,并且人们在互联网选项/代理设置方面遇到了麻烦 - 我没有代理,所以不确定为什么会发生这种情况;

 [exec] Can't do it
 [exec] Traceback (most recent call last):
 [exec]   File "viewEmployeeUseCase.py", line 82, in <module>
 [exec]     ff.save_screenshot('{0}\{1}.png'.format(imagesPath, n))
 [exec]   File "C:\Python26\lib\site-packages\selenium-2.20.0-py2.6.egg\selenium\webdriver\firefox\webdriver.py", line 75, in save_screenshot
 [exec]     png = RemoteWebDriver.execute(self, Command.SCREENSHOT)['value']

 [exec]   File "C:\Python26\lib\site-packages\selenium-2.20.0-py2.6.egg\selenium\webdriver\remote\webdriver.py", line 151, in execute
 [exec]     response = self.command_executor.execute(driver_command, params)

 [exec]   File "C:\Python26\lib\site-packages\selenium-2.20.0-py2.6.egg\selenium\webdriver\remote\remote_connection.py", line 280, in execute
 [exec]     return self._request(url, method=command_info[0], data=data)
 [exec]   File "C:\Python26\lib\site-packages\selenium-2.20.0-py2.6.egg\selenium\webdriver\remote\remote_connection.py", line 321, in _request
 [exec]     response = opener.open(request)
 [exec]   File "C:\Python26\lib\urllib2.py", line 391, in open
 [exec]     response = self._open(req, data)
 [exec]   File "C:\Python26\lib\urllib2.py", line 409, in _open
 [exec]     '_open', req)
 [exec]   File "C:\Python26\lib\urllib2.py", line 369, in _call_chain
 [exec]     result = func(*args)
 [exec]   File "C:\Python26\lib\urllib2.py", line 1170, in http_open
 [exec]     return self.do_open(httplib.HTTPConnection, req)
 [exec]   File "C:\Python26\lib\urllib2.py", line 1145, in do_open
 [exec]     raise URLError(err)
 [exec] urllib2.URLError: <urlopen error [Errno 10061] No connection could be made because the target machine actively refused it>

让事情变得简单,不用等待内容填充就可以正常工作,并且可以通过以下方式实现我想要的一切;

for option in detailsAccordion:
    #print option
    option.click()
    WebDriverWait(ff, 2)
    n = nextNumber(n)
    ff.save_screenshot('{0}\{1}.png'.format(imagesPath, n))
    option.click()

最佳答案

我不认为隐式等待是您想要的,并且我不相信它在您的代码中执行任何操作。 “隐式等待是告诉WebDriver在尝试查找一个或多个元素(如果它们不能立即可用)时轮询DOM一段时间。默认设置为0。一旦设置,隐式等待就会设置为生命周期WebDriver 对象实例的。” -Webdriver

你真正想要的是 explicit wait等待 Accordion 内容出现,然后截取屏幕截图。

抱歉,我不是 Python 程序员,所以我猜测确切的代码。但我认为你想要这样的东西:

detailsAccordion = browser.find_elements_by_class_name('accordion')
for option in detailsAccordion:
    option.click() # open div
    #Wait until the accordionContent div has text
    try:
        element = WebDriverWait(browser, 10).until(lambda option : option.find_element_by_class_name("accordionContent").text != "" )
    finally:
        #Throw error cause the div didn't populate
        browser.quit
    n = nextNumber(n)
    browser.save_screenshot('{0}\{1}.png'.format(imagesPath, n))
    option.click() #close div

更新:抱歉,我认为我最初建议的解决方案存在两个主要问题。 (1) 应该是 except: 而不是 finally:,因为 finally: 总是执行,而不仅仅是在出现超时错误时执行。 (2) 与 Watir-Webdriver 不同,Selenium-Webdriver 似乎不允许检查当前 accordion 元素的 accordionContent 。最初提出的解决方案总是检查页面上的第一个 accordionContent (不好)。我可以找到相对于另一个元素的元素的唯一方法是使用 xpath (或 css-selector)。

以下内容已根据这两个概念进行了更新:

detailsAccordion = browser.find_elements_by_class_name('accordion')
index = 1
for option in detailsAccordion:
    print option
    option.click()
    try:
        element = ui.WebDriverWait(browser, 10).until(lambda driver : driver.find_element_by_xpath("//div[@class='accordion'][" + str(index) + "]/div[@class='accordionContent']").text != "" )
    except:
        # Error if div didn't populate
        print "Can't do it"
        browser.quit()
    index = index + 1
    n = nextNumber(n)
    browser.save_screenshot('{0}\{1}.png'.format(imagesPath, n))
    option.click()

关于python - 使用 Selenium 和 Python 迭代 Accordion block 中的每个项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10091375/

相关文章:

python - 将 PIL 图像转换为字节数组?

selenium - TestNG 报告器 org.testng.reporters.JUnitReportReporter@7a79be86 失败 java.util.ConcurrentModificationException

python - 如何使用 boto 检索 ec2-image 的状态?

python - 使用 Django 将上传的图像保存到 S3

python - 在 Django 模型中保存 Facebook 图片(REST Social Oauth2)

python - Twisted 无缘无故抛出 "Can only pass-through bytes on Python 2"

python - 如何在 python 中从 perforce check out 文件?

java - 如何使用 Selenium 将值输入到表格中的一组文本字段

java - 在文本字段中输入明天的日期

python - 如果 AWS 实例没有使用 Python 关联的名称标签,则无法打印 "Unknown"