鸽了好久的selenium第二篇,磨磨蹭蹭到今天才发出来,其实一方面是最近拖延症比较严重,另一方面是最近开始学习前端的知识,对于网页元素、css样式和js代码,有了一些了解,再回过头来看selenium的选择方法理解更透彻了。
CSS表达式选择
上一篇在选择网页元素的时候是通过调用不同的python方法来对不同的网页元素进行选择,但在比较复杂的网页中,网页元素的属性会较为复杂,仅仅通过一种方法选择网页元素时容易出现多选或者漏选的情况。
而这时候就可以通过CSS表达式进行选择,CSS作为前端三大件之一,在网页设计中用来给特定元素添加自定义样式,因此在网页元素选择方面是极为强大的,而在python中调用也很简单。
普通选择
选择单个元素
find_element_by_css_selector(CSS表达式参数)
选择所有符合条件的元素
find_elements_by_css_selector(CSS表达式参数)
选择所有的tag名为div的元素
elements = wd.find_elements_by_css_selector('div')
根据id属性选择
element = wd.find_element_by_css_selector('#searchtext')
根据class属性
elements = wd.find_elements_by_css_selector('.animal')
直接子元素和后代元素
在网页中,经常会有元素嵌套的情况,在这样嵌套的时候,是一层层包裹起来的。
当B元素被A元素包裹时,B元素时A元素的后代元素。
当B元素只被A元素包裹时,中间没有其他层级时,B元素就是A元素的直接子元素。
综合以上定义,直接子元素时后代元素的特例。
这样在选择元素时可以更加精确。
在选择直接子元素时
elements = wd.find_elements_by_css_selector('元素1 > 元素2 > 元素3')
在选择后代元素时
elements = wd.find_elements_by_css_selector('元素1 元素2 元素3')
最终选择到的是元素3
其他属性选择
id、class等都是网页元素的属性,其他属性也可以用css选择其进行选择。
css 选择器支持通过任何属性来选择元素,语法是用一个方括号 [] 。
根据超链接href选择
element = wd.find_element_by_css_selector('[href="https://www.yumefx.com"]')
前面可以加上标签名的限制,比如 div[class=’search’] 表示 选择所有 标签名为div,且class属性值为search的元素。
根据属性选择,还可以不指定属性值,比如 [href] , 表示选择 所有 具有 属性名 为href 的元素,不管它们的值是什么。
CSS 还可以选择 属性值 包含 某个字符串 的元素
比如, 要选择a节点,里面的href属性包含了 miitbeian 字符串,就可以这样写
a[href*="yumefx"]
如果一个元素具有多个属性
<div class="weapon" ctype="gun">M4</div>
CSS 选择器 可以指定 选择的元素要 同时具有多个属性的限制,像这样
div[class=weapon][ctype=gun]
复杂使用
与网页的CSS样式用法一样,CSS选择器也可以联合使用
多维选择
elements = wd.find_elements_by_css_selector('.animal .cat')
多个选择
elements = wd.find_elements_by_css_selector('.dog , .cat')
按次序选择
父元素的第n个子节点使用 nth-child
span类型的第二个子元素这样写 span:nth-child(2)
如果不加节点类型限制,直接这样写 :nth-child(2)
,就是忽视类型,选择所有位置为第2个的元素
同理,倒数第n个子节点使用nth-last-child
第几个某类型的子节点使用 nth-of-type
倒数第几个某类型的子节点使用 nth-last-of-type
父元素的偶数节点,使用 nth-child(even)
父元素的奇数节点,使用 nth-child(odd)
父元素的某类型偶数节点,使用 nth-of-type(even)
父元素的某类型奇数节点,使用 nth-of-type(odd)
相邻兄弟选择使用+号表示,后续所有兄弟节点使用~表示
frame/窗口切换
有时要选择的元素在<iframe
包裹内,是无法直接选取到的, 在html语法中,frame 元素 或者iframe元素的内部 会包含一个 被嵌入的 另一份html文档。
当使用selenium打开一个网页时,操作范围只在当前网页,并不包含被嵌入的html网页的内容,因此需要切换操作范围。
使用 WebDriver 对象的 switch_to 属性,像这样
wd.switch_to.frame(frame_reference)
其中, frame_reference 可以是 frame 元素的属性 name、ID 或者frame 所对应的 WebElement 对象。
也可以根据frame的元素位置或者属性特性,使用find系列的方法,选择到该元素,得到对应的WebElement对象。
wd.switch_to.frame(wd.find_element_by_tag_name("iframe"))
然后就可以自由操作frame里面的元素了。
切换回原来的主html则可以使用
wd.switch_to.default_content()
切换窗口时,使用Webdriver对象的switch_to属性的 window方法,如下所示:
wd.switch_to.window(handle)
WebDriver对象有window_handles 属性,这是一个列表对象, 里面包括了当前浏览器里面所有的窗口句柄。
所谓句柄,可以想象成对应网页窗口的一个ID,通过 类似下面的代码获取。
for handle in wd.window_handles: # 先切换到该窗口 wd.switch_to.window(handle) # 得到该窗口的标题栏字符串,判断是不是我们要操作的那个窗口 if 'Bing' in wd.title: # 如果是,那么这时候WebDriver对象就是对应的该该窗口,正好,跳出循环, break # mainWindow变量保存当前窗口的句柄 mainWindow = wd.current_window_handle
选择框
radio框
radio框选择选项,直接用WebElement的click方法,模拟用户点击就可以了。
# 获取当前选中的元素 element = wd.find_element_by_css_selector( '#s_radio input[checked=checked]') print('当前选中的是: ' + element.get_attribute('value')) # 点选 小雷老师 wd.find_element_by_css_selector( '#s_radio input[value="小雷老师"]').click()
checkbox框
需要注意的是,要选中checkbox的一个选项,必须 先获取当前该复选框的状态 ,如果该选项已经勾选了,就不能再点击。否则反而会取消选择。
# 先把 已经选中的选项全部点击一下 elements = wd.find_elements_by_css_selector( '#s_checkbox input[checked="checked"]') for element in elements: element.click() # 再点击 小雷老师 wd.find_element_by_css_selector( "#s_checkbox input[value='小雷老师']").click()
select框
radio框及checkbox框都是input元素,只是里面的type不同而已。
select框 则是一个新的select标签,对于Select 选择框, Selenium 专门提供了一个 Select类 进行操作。
Select类 提供了以下方法
- select_by_value
根据选项的 value属性值 ,选择元素。
比如,下面的HTML
<option value="foo">Bar</option>
就可以根据 foo 这个值选择该选项,
s.select_by_value('foo')
- select_by_index
根据选项的 次序 (从0开始),选择元素
- select_by_visible_text
根据选项的 可见文本 ,选择元素。
比如,下面的HTML,
<option value="foo">Bar</option>
就可以根据 Bar 这个内容,选择该选项
s.select_by_visible_text('Bar')
- deselect_by_value
根据选项的value属性值, 去除 选中元素
- deselect_by_index
根据选项的次序,去除 选中元素
- deselect_by_visible_text
根据选项的可见文本,去除 选中元素
- deselect_all
去除 选中所有元素
Select单选框
对于 select单选框,操作比较简单:
不管原来选的是什么,直接用Select方法选择即可。
# 导入Select类 from selenium.webdriver.support.ui import Select # 创建Select对象 select = Select(wd.find_element_by_id("ss_single")) # 通过 Select 对象选中小雷老师 select.select_by_visible_text("小雷老师")
Select多选框
对于select多选框,要选中某几个选项,要注意去掉原来已经选中的选项。
# 导入Select类 from selenium.webdriver.support.ui import Select # 创建Select对象 select = Select(wd.find_element_by_id("ss_multi")) # 清除所有 已经选中 的选项 select.deselect_all() # 选择小雷老师 和 小凯老师 select.select_by_visible_text("小雷老师") select.select_by_visible_text("小凯老师")
本文转载自白月黑羽,稍作精简修改。
已有的事,后必再有;
已行的事,后必再行。
日光之下,并无新事。
——《圣经·传道书》
评论
33587 576114Possible demand all types of led tourdates with some other fancy car applications. Numerous also give historic packs and other requires to order take into your lending center, and for a holiday in upstate New York. ??? 221639
749520 98818Its fantastic as your other articles : D, appreciate it for putting up. 911059