0


python selenium 高级应用:非select下拉框、动态id、无唯一属性定位

前言:接了人生中第一个python单子,用selenium自动化,是一个比较时新的网站,用了大量的js渲染,费了很大的力气,但我也终于发现了——任何人能够进行的浏览器操作都可以用selenium实现。

文章目录

1.非select类下拉框

在非select类下拉框这里遇到了两种需求,一种是可输入字符,一种是不可输入字符

1.1输入部分字符按照智能提示点选

这种下拉框允许输入字符,沟通后确定输入字符如出现多个选项则点选第一个

思路:用

send_keys

输入字符后会激活下拉框进行智能提示,然后用

ActionChains

模拟鼠标点击

在这里插入图片描述

brand =  driver.find_element_by_css_selector('#rc_select_0')
brand.send_keys(lst[1])
time.sleep(0.5)
ActionChains(driver).move_to_element(brand).move_by_offset(0,30).click().perform()#ActionChains(driver).move_to_element(brand).move_by_offset(0,30).context_click().perform()#这里用鼠标先定位到输入框,再往下移一段距离,这里因为不知道移动的距离,所以先用点击左键context_click来观察

1.2不可输入字符

需求:按照指定的内容选择相应的选项
思路:点击一下激活下拉框,因为无法用

Select

模块,所以要先获取全部的选项,然后遍历匹配目标内容,匹配上了则点击相应的元素

在这里插入图片描述
从图片中可以看到这个下拉框是一个变动的,周围没有其他的选项,

activedecendant

属性会跟随鼠标的选择变化,观察看到

aria-owns

来自另一个地方,定位后如下图:
在这里插入图片描述
可以看到定位后出现的也是一个变化的元素,而在它不远处就是所有的选项,是一对

div

标签,于是用

find_elements

获取所有的选项进行匹配,然后再点击该元素即可

driver.find_element_by_xpath("//input[starts-with(@id,'ifDangerous_productList_0')]/../..").click()#点击下拉框激活,如果不激活的话选项元素会被隐藏无法定位
lst_dangerous = driver.find_elements_by_xpath("//div[starts-with(@id,'ifDangerous_productList_0')]/../div[2]/div[1]/div[1]/div[1]/div")#获取选项,形成一个列表for dangerous in lst_dangerous:if lst[12]==dangerous.get_attribute('title'):#遍历匹配
        driver.execute_script('arguments[0].click()',dangerous)

这里要提到一个尚未解决的地方,另一个下拉框与此类似,但因为下拉选项很多,超过了10个,于是在本应展现全部选项的地方仍然展示不全,也是一个变化的状态

在这里插入图片描述

在这里插入图片描述
找了半天也没有找到能获取全部选项的地方,好在这个下拉框允许输入,通过输入再模拟鼠标点击解决了,不知道有没有更好的办法

2.定位动态id和无唯一属性元素

2.1定位动态id

在这个网页中很多元素都是动态id,因此无法直接用id定位
在这里插入图片描述
如上图,后一半是动态生成的,但前一半是固定的,可以通过

xpath

表达式进行定位

driver.find_element_by_xpath("//标签名[starts-with(@属性名, 'xxx')]")#以xxx开头的属性的标签
driver.find_element_by_xpath("//标签名[ends-with(@属性名, 'xxx')]")#以xxx结尾的属性的标签
driver.find_element_by_xpath("//标签名[contains(@属性名, 'xxx')]")#包含xxx的属性的标签

2.2定位无唯一属性元素

本身无唯一属性,也可以通过

xpath

css_selector

的绝对位置来定位,可是网站上有很多隐藏的元素,在特定的时候会出现,所以会导致绝对位置变化,如果要实现每次定位都能成功,应该尽可能使用相对位置

思路:先定位到周围有唯一属性的元素,再通过该元素定位到目标元素

driver.find_element_by_xpath("//div[@id='xxx']/A")#由id为xxx的父元素定位到子元素A
driver.find_element_by_xpath("//div[@id='xxx']/..")#由id为xxx的子元素定位到其父元素
driver.find_element_by_xpath("//div[@id='xxx']/../A")#由id为xxx的子元素定位到其同级元素A(先定位到父元素)

在这里插入图片描述

lst_dangerous = driver.find_elements_by_xpath("//div[starts-with(@id,'ifDangerous_productList_0')]/../div[2]/div[1]/div[1]/div[1]/div")

如前面所说的下拉框,就是通过id=ifDangerous_productList_0_…这个元素,定位到父元素,在逐步定位到目标元素

3.通过JS解决点击被遮挡的问题

有时实行点击时,会被遮挡或不在范围内,可以采用执行JS

ele=driver.find_element_by_xpath("//input[starts-with(@id,'chemicaltype_productList_0')]/../..").
driver.execute_script('arguments[0].click()',ele)

4.非input上传文件

input上传文件只要用

send_keys

输入路径即可,非input会触发windows控件,但是selenium无法操控windows,于是要使用

pywinauto

#点击上传按钮,触发窗口
upload1 = driver.find_element_by_xpath("//div[text()='MSDS文件:']//../div[2]/span[1]/div[1]/span[1]/button[1]")
driver.execute_script('arguments[0].click()',upload1)#通过窗口打开
app = pywinauto.Desktop()#通过弹窗名称进入控件
win = app['文件上传']#输入路径
win['Edit'].type_keys(path +'\\'+file)#点击打开按钮
win['Button'].click()

需要提醒的两点是:
通过弹窗名称进入控件时要注意不同浏览器的名称不一样,如火狐浏览器是“上传文件”,谷歌浏览器是“打开”
不能使用360安全卫士,否则会报错

标签: selenium python

本文转载自: https://blog.csdn.net/redemption77/article/details/124436279
版权归原作者 redemption77 所有, 如有侵权,请联系我们删除。

“python selenium 高级应用:非select下拉框、动态id、无唯一属性定位”的评论:

还没有评论