我真的是很懒,一般用Selenium都是用time.sleep(1),这里等一秒,那里等一秒,不知不觉效率就变得很低了。

等的时间长效率就低,等的时间短经常报错,效率更低。今天终于花了个几分钟把代码改了,这下这个傻逼的自动化小工具就没那么傻逼了。

为了督促我以后多使用wait,今天把基础用法备份过来,便于以后抄袭。

from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

By是定位用的,WebDriverWait就是显式等待,EC是预期条件(等到什么时候)。

比如下面这个小例子:

WebDriverWait(driver, 10).until(
        EC.element_to_be_clickable((By.XPATH, '************'))
    ).click()

意思是,等xpath对应的元素可以点击的时候点击它,但不要等超过10秒。

EC还有别的常用的条件:

title_is
title_contains
presence_of_element_located
visibility_of_element_located
visibility_of
presence_of_all_elements_located
text_to_be_present_in_element
text_to_be_present_in_element_value
frame_to_be_available_and_switch_to_it
invisibility_of_element_located
element_to_be_clickable
staleness_of
element_to_be_selected
element_located_to_be_selected
element_selection_state_to_be
element_located_selection_state_to_be
alert_is_present

希望我以后别懒了。


或者说,有个稍微复杂点的情况,比如有可能出现一个别的元素,我在出现这个意外元素的时候也需要停止等待(多条件Wait),那我可以写一个别的类或者方法,比如:

def select_element(driver):
    try:
        return EC.presence_of_element_located((By.XPATH, 'xpath1'))(driver)
    except:
        return EC.element_to_be_clickable((By.XPATH, 'xpath2'))(driver)

然后再调用wait方法:

element = WebDriverWait(driver, 10).until(select_element)

这样的话,如果xpath1的元素出现的时候,返回xpath1对应的元素,如果xpath1对应的元素没有出现,而xpath2对应的元素可以点击的话,返回xpath2对应的元素。


还有一种情形可能也会用到,就是把鼠标悬浮在某个元素上才会显示新的元素,那么就要用到ActionChains了

from selenium.webdriver.common.action_chains import ActionChains

ActionChains(driver).move_to_element(element).perform()