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

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

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



文章目录
  • 1.非select类下拉框
    • 1.1输入部分字符按照智能提示点选
    • 1.2不可输入字符
  • 2.定位动态id和无唯一属性元素
    • 2.1定位动态id
    • 2.2定位无唯一属性元素
  • 3.通过JS解决点击被遮挡的问题
  • 4.非input上传文件




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定位无唯一属性元素

本身无唯一属性,也可以通过xpathcss_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()
#通过d窗名称进入控件
win = app['文件上传']
#输入路径
win['Edit'].type_keys(path + '\' + file)
#点击打开按钮
win['Button'].click()

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

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/786115.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-04
下一篇 2022-05-04

发表评论

登录后才能评论

评论列表(0条)

保存