【问题标题】:Selenium click does not trigger event on website (python)Selenium 点击不会在网站上触发事件(python)
【发布时间】:2015-09-28 06:43:39
【问题描述】:

有时当我使用 selenium 点击页面上的特定链接时,点击会通过,但网站不会响应点击。例如,当我尝试在 nba.com 的统计页面上的日期之间导航时,就会出现这种情况。

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as ec

import datetime
import time

def go_to_next_day(driver, next_date):
    for elem in driver.find_elements_by_css_selector('.date-selector i'):
        if 'right' in elem.get_attribute('class'):
            print 'Found next day!'
            elem.click()
            break
    else:
        raise ValueError('Unable to navigate to the next day')

    # wait 30 seconds until the next day loads
    WebDriverWait(driver, 30).until(
        ec.text_to_be_present_in_element((By.CSS_SELECTOR, '.date-selector > span'), next_date.strftime('%m/%d/%Y'))
    )


if __name__ == '__main__':
    # go to nba.com
    driver = webdriver.Firefox()
    driver.set_window_size(2560, 1600)
    driver.get('http://stats.nba.com/scores/#!/10/03/2014')

    print 'NBA.com loaded. Clicking to next day!!!'
    end_date = datetime.datetime.now()
    current_date = datetime.datetime.strptime('2014-10-03', '%Y-%m-%d')

    # after page loads, just click right until you get to current date
    while current_date <= end_date:
        # do something interesting on the page, modeled as a sleep
        time.sleep(1)

        next_date = current_date + datetime.timedelta(days=1)
        go_to_next_day(driver, next_date)
        current_date = next_date
        print 'Went to day {}'.format(current_date)

    driver.quit()
    print 'Done'

为什么脚本总是点击,但网站有时只改变页面?是something to do with angular? 我怀疑它与操作系统有什么关系,但我在 Mac OS X 上。

我不确定并且真的很想弄清楚如何避免点击失败,特别是因为我认为我点击并以 selenium 方式等待。

【问题讨论】:

    标签: javascript python angularjs selenium selenium-webdriver


    【解决方案1】:

    问题是如果当天的数据仍在加载,则点击不会使其转到第二天。换句话说,如果“加载微调器”可见 - 单击 > 按钮无效。

    解决它:等待包含微调器的 div.loader 元素不可见

    def go_to_next_day(driver, next_date):
        wait = WebDriverWait(driver, 10)
        actions = ActionChains(driver)
        try:
            next_button = wait.until(ec.element_to_be_clickable((By.CSS_SELECTOR, '.date-selector i[class*=right]')))
            actions.move_to_element(next_button).click().perform()
        except TimeoutException:
            raise ValueError('Unable to navigate to the next day')
    
        # THIS IS THE KEY FIX
        wait.until(ec.invisibility_of_element_located((By.CSS_SELECTOR, "div.loader")))
    
        # wait until the next day loads
        wait.until(
            ec.text_to_be_present_in_element((By.CSS_SELECTOR, '.date-selector > span'), next_date.strftime('%m/%d/%Y'))
        )
    

    我对下一个按钮的操作也略有不同,请随意继续您自己的方法或切换到我的方法 - 关键修复是等待“微调器”隐身。对我有用。

    【讨论】:

    • 所以在这种情况下,我可以直接查看一个元素以确保页面正确加载。如果没有像 div.loader 这样的元素怎么办?还有什么是使用 ActionChains 而不是点击的固有优势?
    • @AkshayDongaonkar 这个问题实际上是特定于网站的。我通常使用这个“技巧”来等待“加载”图标/微调器等在加载过程中不可见。而更多时候,我只是等待所需的内容出现 - 显式等待具有所需数据的容器的可见性/存在。
    • @AkshayDongaonkar 动作链在这种情况下有助于将鼠标悬停在元素上然后单击 - 有时它有助于解决“单击”问题。我很确定你在这里实际上不需要动作链。
    • yupp 我通常会等待一个明确的元素表明内容已加载。但是,在某些情况下,由于页面尚未完全加载,我已经完成了对页面的快速处理,以至于导航无法正常工作。我只是想知道是否有灵丹妙药告诉我 DOM 是否完全稳定并且 javascript 是否已停止运行。
    • @AkshayDongaonkar 是的,严格来说,没有灵丹妙药。我认为符合预期条件的 webdriverwait 是最实用的方法。
    猜你喜欢
    • 1970-01-01
    • 2015-12-06
    • 1970-01-01
    • 2018-04-18
    • 2020-12-27
    • 1970-01-01
    • 2013-05-19
    • 2015-12-19
    相关资源
    最近更新 更多