Selenium locates the hidden element and cannot find notvisio_exception or no suchelement selenium.common.exceptions.ElementNotVisibleException: Message: element not visible Processing method: selenium's handling of drop-down menu events

selenium.common.exceptions.ElementNotVisibleException: Message: element not visible Handling method: selenium's handling of drop-down menu events

When using Selenium crawlers, you may encounter some drop-down menus, which are loaded dynamically. If you use the find_element_by_ function directly, an error will be reported, showing selenium.common.exceptions.ElementNotVisibleException: Message: element not visible.

Means element is invisible. So can't get it. At this time, I encountered a problem, how to make the element visible?

At this time, we use ActionChains to simulate the effect

ActionChains(driver).click(driver.find_element(By.ID, 'g-hd-searchs')).perform() #Use perform() to execute action

 At this time, you will be surprised to find that the drop-down menu appears successfully.

 Next, you can do what you want.

The following introduces ActionChains:

Using selenium for automation, sometimes you need to simulate mouse operations to perform, such as single-click, double-click, right-click, drag and drop, and so on. And selenium provides us with a class to handle such events - ActionChains

selenium.webdriver.common.action_chains.ActionChains(driver)

This class can basically meet all our needs for mouse operation.

1. Basic usage of ActionChains

First of all, you need to understand the execution principle of ActionChains. When you call the method of ActionChains, it will not be executed immediately, but will store all operations in a queue in order. When you call the perform() method, the time in the queue will be Execute in sequence.

In this case we can have two calling methods:

  • chain writing

    menu = driver.find_element_by_css_selector(".nav")
    hidden_submenu =    driver.find_element_by_css_selector(".nav #submenu1")
    
    ActionChains(driver).move_to_element(menu).click(hidden_submenu).perform()
  • step by step
  • menu = driver.find_element_by_css_selector(".nav")
    hidden_submenu = driver.find_element_by_css_selector(".nav #submenu1")
    
    actions = ActionChains(driver)
    actions.move_to_element(menu) actions.click(hidden_submenu) actions.perform()
  • The essence of the two writing methods is the same, and ActionChains will perform all operations in order.

2.ActionChains method list

click ( on_element=None ) - click the left mouse button

click_and_hold ( on_element=None ) - click the left mouse button without releasing it

context_click ( on_element=None ) - click the right mouse button

double_click ( on_element=None ) - double click the left mouse button

drag_and_drop ( source, target ) - drag to an element and release

drag_and_drop_by_offset ( source, xoffset, yoffset ) - drag to a certain coordinate and release

key_down ( value, element=None ) - press a key on a keyboard

key_up ( value, element=None ) - release a key

move_by_offset ( xoffset , yoffset ) - move the mouse from the current position to a certain coordinate

move_to_element ( to_element ) - move the mouse to an element

move_to_element_with_offset ( to_element, xoffset, yoffset ) - move to a position how far away from an element (coordinates of the upper left corner)

perform () - perform all actions in the chain

release ( on_element=None ) - release the left mouse button at an element position

send_keys ( *keys_to_send ) - send a key to the currently focused element

send_keys_to_element ( element, *keys_to_send ) - send a key to the specified element

Next, an example is used to explain and demonstrate the usage of each method in detail:

3. Code example

1. Click Action

Example URL http://sahitest.com/demo/clicks.htm

Code:

# -*- coding: utf-8 -*-

from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains from time import sleep driver = webdriver.Firefox() driver.implicitly_wait(10) driver.maximize_window() driver.get('http://sahitest.com/demo/clicks.htm') click_btn = driver.find_element_by_xpath('//input[@value="click me"]') # 单击按钮 doubleclick_btn = driver.find_element_by_xpath('//input[@value="dbl click me"]') # 双击按钮 rightclick_btn = driver.find_element_by_xpath('//input[@value="right click me"]') # 右键单击按钮 ActionChains(driver).click(click_btn).double_click(doubleclick_btn).context_click(rightclick_btn).perform() # 链式用法 print driver.find_element_by_name('t2').get_attribute('value') sleep(2) driver.quit()

result:

[CLICK][DOUBLE_CLICK][RIGHT_CLICK]

2. Mouse movement

Example URL http://sahitest.com/demo/mouseover.htm

Sample code:

# -*- coding: utf-8 -*-

from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains from time import sleep driver = webdriver.Firefox() driver.implicitly_wait(10) driver.maximize_window() driver.get('http://sahitest.com/demo/mouseover.htm') write = driver.find_element_by_xpath('//input[@value="Write on hover"]') # 鼠标移动到此元素,在下面的input框中会显示“Mouse moved” blank = driver.find_element_by_xpath('//input[@value="Blank on hover"]') # 鼠标移动到此元素,会清空下面input框中的内容 result = driver.find_element_by_name('t1') action = ActionChains(driver) action.move_to_element(write).perform() # 移动到write,显示“Mouse moved” print result.get_attribute('value') # action.move_to_element(blank).perform() action.move_by_offset(10, 50).perform() # 移动到距离当前位置(10,50)的点,与上句效果相同,移动到blank上,清空 print result.get_attribute('value') action.move_to_element_with_offset(blank, 10, -40).perform() # 移动到距离blank元素(10,-40)的点,可移动到write上 print result.get_attribute('value') sleep(2) driver.quit()

result

Mouse moved

Mouse moved

Generally, the position relationship is rarely used to move the mouse. If necessary, you can refer to the following link to measure the position of the element

http://jingyan.baidu.com/article/eb9f7b6d87e2ae869264e847.html

3. Drag and drop

Example URL http://sahitest.com/demo/dragDropMooTools.htm

Code:

# -*- coding: utf-8 -*-

from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains from time import sleep driver = webdriver.Firefox() driver.implicitly_wait(10) driver.maximize_window() driver.get('http://sahitest.com/demo/dragDropMooTools.htm') dragger = driver.find_element_by_id('dragger') # 被拖拽元素 item1 = driver.find_element_by_xpath('//div[text()="Item 1"]') # 目标元素1 item2 = driver.find_element_by_xpath('//div[text()="Item 2"]') # 目标2 item3 = driver.find_element_by_xpath('//div[text()="Item 3"]') # 目标3 item4 = driver.find_element_by_xpath('//div[text()="Item 4"]') # 目标4 action = ActionChains(driver) action.drag_and_drop(dragger, item1).perform() # 1.移动dragger到目标1 sleep(2) action.click_and_hold(dragger).release(item2).perform() # 2.效果与上句相同,也能起到移动效果 sleep(2) action.click_and_hold(dragger).move_to_element(item3).release().perform() # 3.效果与上两句相同,也能起到移动的效果 sleep(2) # action.drag_and_drop_by_offset(dragger, 400, 150).perform() # 4.移动到指定坐标 action.click_and_hold(dragger).move_by_offset(400, 150).release().perform() # 5.与上一句相同,移动到指定坐标 sleep(2) driver.quit()

result:

dropped dropped dropped dropped

Generally, coordinate positioning is rarely used. It is enough to use method 1 in the above example. If you look at the source code, you will find that method 2 is actually the implementation of drag_and_drop() in method 1. Note: Pay attention to adding waiting time when dragging, sometimes it will fail because the speed is too fast.

4. Button

There are many ways to simulate keys, which can be implemented by win32api, by SendKeys, or by the send_keys() method of selenium's WebElement object. The ActionChains class also provides several methods for simulating keys.

Example URL http://sahitest.com/demo/keypress.htm

Code 1:

# -*- coding: utf-8 -*-

from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains from time import sleep driver = webdriver.Firefox() driver.implicitly_wait(10) driver.maximize_window() driver.get('http://sahitest.com/demo/keypress.htm') key_up_radio = driver.find_element_by_id('r1') # 监测按键升起 key_down_radio = driver.find_element_by_id('r2') # 监测按键按下 key_press_radio = driver.find_element_by_id('r3') # 监测按键按下升起 enter = driver.find_elements_by_xpath('//form[@name="f1"]/input')[1] # 输入框 result = driver.find_elements_by_xpath('//form[@name="f1"]/input')[0] # 监测结果 # 监测key_down key_down_radio.click() ActionChains(driver).key_down(Keys.CONTROL, enter).key_up(Keys.CONTROL).perform() print result.get_attribute('value') # 监测key_up key_up_radio.click() enter.click() ActionChains(driver).key_down(Keys.SHIFT).key_up(Keys.SHIFT).perform() print result.get_attribute('value') # 监测key_press key_press_radio.click() enter.click() ActionChains(driver).send_keys('a').perform() print result.get_attribute('value') driver.quit()

result:

key downed charCode=[0] keyCode=[17] CTRL
key upped charCode=[0] keyCode=[16] NONE key pressed charCode=[97] keyCode=[0] NONE

Example 2:

Example URL http://sahitest.com/demo/label.htm

Code:

# -*- coding: utf-8 -*-

from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains from selenium.webdriver.common.keys import Keys from time import sleep driver = webdriver.Firefox() driver.implicitly_wait(10) driver.maximize_window() driver.get('http://sahitest.com/demo/label.htm') input1 = driver.find_elements_by_tag_name('input')[3] input2 = driver.find_elements_by_tag_name('input')[4] action = ActionChains(driver) input1.click() action.send_keys('Test Keys').perform() action.key_down(Keys.CONTROL).send_keys('a').key_up(Keys.CONTROL).perform() # ctrl+a action.key_down(Keys.CONTROL).send_keys('c').key_up(Keys.CONTROL).perform() # ctrl+c action.key_down(Keys.CONTROL, input2).send_keys('v').key_up(Keys.CONTROL).perform() # ctrl+v print input1.get_attribute('value') print input2.get_attribute('value') driver.quit()

result:

Test Keys
Test Keys

Copy and paste can also be achieved with WebElement<input>.send_keys(). You can try it, or you can use a lower-level method. It is also one of the ways to deal with the os pop-up box, win32api. If you are interested, you can also try SendKeys, keybd_event

When using Selenium crawlers, you may encounter some drop-down menus, which are loaded dynamically. If you use the find_element_by_ function directly, an error will be reported, showing selenium.common.exceptions.ElementNotVisibleException: Message: element not visible.

Means element is invisible. So can't get it. At this time, I encountered a problem, how to make the element visible?

At this time, we use ActionChains to simulate the effect

ActionChains(driver).click(driver.find_element(By.ID, 'g-hd-searchs')).perform() #Use perform() to execute action

 At this time, you will be surprised to find that the drop-down menu appears successfully.

 Next, you can do what you want.

The following introduces ActionChains:

Using selenium for automation, sometimes you need to simulate mouse operations to perform, such as single-click, double-click, right-click, drag and drop, and so on. And selenium provides us with a class to handle such events - ActionChains

selenium.webdriver.common.action_chains.ActionChains(driver)

This class can basically meet all our needs for mouse operation.

1. Basic usage of ActionChains

First of all, you need to understand the execution principle of ActionChains. When you call the method of ActionChains, it will not be executed immediately, but will store all operations in a queue in order. When you call the perform() method, the time in the queue will be Execute in sequence.

In this case we can have two calling methods:

  • chain writing

    menu = driver.find_element_by_css_selector(".nav")
    hidden_submenu =    driver.find_element_by_css_selector(".nav #submenu1")
    
    ActionChains(driver).move_to_element(menu).click(hidden_submenu).perform()
  • step by step
  • menu = driver.find_element_by_css_selector(".nav")
    hidden_submenu = driver.find_element_by_css_selector(".nav #submenu1")
    
    actions = ActionChains(driver)
    actions.move_to_element(menu) actions.click(hidden_submenu) actions.perform()
  • The essence of the two writing methods is the same, and ActionChains will perform all operations in order.

2.ActionChains method list

click ( on_element=None ) - click the left mouse button

click_and_hold ( on_element=None ) - click the left mouse button without releasing it

context_click ( on_element=None ) - click the right mouse button

double_click ( on_element=None ) - double click the left mouse button

drag_and_drop ( source, target ) - drag to an element and release

drag_and_drop_by_offset ( source, xoffset, yoffset ) - drag to a certain coordinate and release

key_down ( value, element=None ) - press a key on a keyboard

key_up ( value, element=None ) - release a key

move_by_offset ( xoffset , yoffset ) - move the mouse from the current position to a certain coordinate

move_to_element ( to_element ) - move the mouse to an element

move_to_element_with_offset ( to_element, xoffset, yoffset ) - move to a position how far away from an element (coordinates of the upper left corner)

perform () - perform all actions in the chain

release ( on_element=None ) - release the left mouse button at an element position

send_keys ( *keys_to_send ) - send a key to the currently focused element

send_keys_to_element ( element, *keys_to_send ) - send a key to the specified element

Next, an example is used to explain and demonstrate the usage of each method in detail:

3. Code example

1. Click Action

Example URL http://sahitest.com/demo/clicks.htm

Code:

# -*- coding: utf-8 -*-

from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains from time import sleep driver = webdriver.Firefox() driver.implicitly_wait(10) driver.maximize_window() driver.get('http://sahitest.com/demo/clicks.htm') click_btn = driver.find_element_by_xpath('//input[@value="click me"]') # 单击按钮 doubleclick_btn = driver.find_element_by_xpath('//input[@value="dbl click me"]') # 双击按钮 rightclick_btn = driver.find_element_by_xpath('//input[@value="right click me"]') # 右键单击按钮 ActionChains(driver).click(click_btn).double_click(doubleclick_btn).context_click(rightclick_btn).perform() # 链式用法 print driver.find_element_by_name('t2').get_attribute('value') sleep(2) driver.quit()

result:

[CLICK][DOUBLE_CLICK][RIGHT_CLICK]

2. Mouse movement

Example URL http://sahitest.com/demo/mouseover.htm

Sample code:

# -*- coding: utf-8 -*-

from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains from time import sleep driver = webdriver.Firefox() driver.implicitly_wait(10) driver.maximize_window() driver.get('http://sahitest.com/demo/mouseover.htm') write = driver.find_element_by_xpath('//input[@value="Write on hover"]') # 鼠标移动到此元素,在下面的input框中会显示“Mouse moved” blank = driver.find_element_by_xpath('//input[@value="Blank on hover"]') # 鼠标移动到此元素,会清空下面input框中的内容 result = driver.find_element_by_name('t1') action = ActionChains(driver) action.move_to_element(write).perform() # 移动到write,显示“Mouse moved” print result.get_attribute('value') # action.move_to_element(blank).perform() action.move_by_offset(10, 50).perform() # 移动到距离当前位置(10,50)的点,与上句效果相同,移动到blank上,清空 print result.get_attribute('value') action.move_to_element_with_offset(blank, 10, -40).perform() # 移动到距离blank元素(10,-40)的点,可移动到write上 print result.get_attribute('value') sleep(2) driver.quit()

result

Mouse moved

Mouse moved

Generally, the position relationship is rarely used to move the mouse. If necessary, you can refer to the following link to measure the position of the element

http://jingyan.baidu.com/article/eb9f7b6d87e2ae869264e847.html

3. Drag and drop

Example URL http://sahitest.com/demo/dragDropMooTools.htm

Code:

# -*- coding: utf-8 -*-

from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains from time import sleep driver = webdriver.Firefox() driver.implicitly_wait(10) driver.maximize_window() driver.get('http://sahitest.com/demo/dragDropMooTools.htm') dragger = driver.find_element_by_id('dragger') # 被拖拽元素 item1 = driver.find_element_by_xpath('//div[text()="Item 1"]') # 目标元素1 item2 = driver.find_element_by_xpath('//div[text()="Item 2"]') # 目标2 item3 = driver.find_element_by_xpath('//div[text()="Item 3"]') # 目标3 item4 = driver.find_element_by_xpath('//div[text()="Item 4"]') # 目标4 action = ActionChains(driver) action.drag_and_drop(dragger, item1).perform() # 1.移动dragger到目标1 sleep(2) action.click_and_hold(dragger).release(item2).perform() # 2.效果与上句相同,也能起到移动效果 sleep(2) action.click_and_hold(dragger).move_to_element(item3).release().perform() # 3.效果与上两句相同,也能起到移动的效果 sleep(2) # action.drag_and_drop_by_offset(dragger, 400, 150).perform() # 4.移动到指定坐标 action.click_and_hold(dragger).move_by_offset(400, 150).release().perform() # 5.与上一句相同,移动到指定坐标 sleep(2) driver.quit()

result:

dropped dropped dropped dropped

Generally, coordinate positioning is rarely used. It is enough to use method 1 in the above example. If you look at the source code, you will find that method 2 is actually the implementation of drag_and_drop() in method 1. Note: Pay attention to adding waiting time when dragging, sometimes it will fail because the speed is too fast.

4. Button

There are many ways to simulate keys, which can be implemented by win32api, by SendKeys, or by the send_keys() method of selenium's WebElement object. The ActionChains class also provides several methods for simulating keys.

Example URL http://sahitest.com/demo/keypress.htm

Code 1:

# -*- coding: utf-8 -*-

from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains from time import sleep driver = webdriver.Firefox() driver.implicitly_wait(10) driver.maximize_window() driver.get('http://sahitest.com/demo/keypress.htm') key_up_radio = driver.find_element_by_id('r1') # 监测按键升起 key_down_radio = driver.find_element_by_id('r2') # 监测按键按下 key_press_radio = driver.find_element_by_id('r3') # 监测按键按下升起 enter = driver.find_elements_by_xpath('//form[@name="f1"]/input')[1] # 输入框 result = driver.find_elements_by_xpath('//form[@name="f1"]/input')[0] # 监测结果 # 监测key_down key_down_radio.click() ActionChains(driver).key_down(Keys.CONTROL, enter).key_up(Keys.CONTROL).perform() print result.get_attribute('value') # 监测key_up key_up_radio.click() enter.click() ActionChains(driver).key_down(Keys.SHIFT).key_up(Keys.SHIFT).perform() print result.get_attribute('value') # 监测key_press key_press_radio.click() enter.click() ActionChains(driver).send_keys('a').perform() print result.get_attribute('value') driver.quit()

result:

key downed charCode=[0] keyCode=[17] CTRL
key upped charCode=[0] keyCode=[16] NONE key pressed charCode=[97] keyCode=[0] NONE

Example 2:

Example URL http://sahitest.com/demo/label.htm

Code:

# -*- coding: utf-8 -*-

from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains from selenium.webdriver.common.keys import Keys from time import sleep driver = webdriver.Firefox() driver.implicitly_wait(10) driver.maximize_window() driver.get('http://sahitest.com/demo/label.htm') input1 = driver.find_elements_by_tag_name('input')[3] input2 = driver.find_elements_by_tag_name('input')[4] action = ActionChains(driver) input1.click() action.send_keys('Test Keys').perform() action.key_down(Keys.CONTROL).send_keys('a').key_up(Keys.CONTROL).perform() # ctrl+a action.key_down(Keys.CONTROL).send_keys('c').key_up(Keys.CONTROL).perform() # ctrl+c action.key_down(Keys.CONTROL, input2).send_keys('v').key_up(Keys.CONTROL).perform() # ctrl+v print input1.get_attribute('value') print input2.get_attribute('value') driver.quit()

result:

Test Keys
Test Keys

Copy and paste can also be achieved with WebElement<input>.send_keys(). You can try it, or you can use a lower-level method. It is also one of the ways to deal with the os pop-up box, win32api. If you are interested, you can also try SendKeys, keybd_event

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324684989&siteId=291194637