元素找不到可能的原因:
元素定位的表达式不对没有设置等待,或者设置等待时间太少根本不在这个页面(另外一个窗口,在一个iframe当中)
最好不要用的值定位元素:
属性值中有数字,数字可能会变化不认识的莫名其妙的字符串(加密),也有可能动态生成class里面的active hidden
1.窗口切换
窗口切换后要注意设置时间等待,否则会报错
from selenium import webdriverfrom mon.by import Byfrom selenium.webdriver.support.wait import WebDriverWaitfrom selenium.webdriver.support import expected_conditions as whenclass TestDeom:def test_01(self):with webdriver.Chrome() as browser:browser.get('/')# browser.implicitly_wait(5)el = browser.find_element(By.XPATH, '//input[@id="kw"]')el.send_keys('柠檬班')search_button = browser.find_element(By.ID, 'su')search_button.click()# 设置显性等级# 1.等待器,设置倒计时# 2.等待条件出现# 3.在超时前,如果等待条件出现了,如果等待条件没有出现,会报超时错误wait = WebDriverWait(browser, timeout=10)# 注意等待某个元素是传入元组或列表condition = when.element_to_be_clickable((By.LINK_TEXT, 'lemon./'))lemon_link = wait.until(condition)# 打印切换窗口前的第一个窗口print(browser.current_window_handle)lemon_link.click()# 打印所有窗口print(browser.window_handles)# 切换到新页面,因为是列表,所以要选择最后一个browser.switch_to.window(browser.window_handles[-1])print(browser.current_window_handle)browser.find_element(By.CSS_SELECTOR, '.agency-content')
运行结果:
2.iframe切换
例子一:
新建一个html文件,代码如下:
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>py44</title></head><body><!-- 标题--><h2 id="hello">hello</h2><iframe id="i" name="f" src="" width="800px" height="600px"></iframe></form></body></html>
然后找到本地编写html文件的路径,来访问
iframe切换代码如下:
from selenium import webdriverfrom mon.by import Byfrom selenium.webdriver.support.wait import WebDriverWaitfrom selenium.webdriver.support import expected_conditions as whenclass TestDeom:def test_01(self):with webdriver.Chrome() as browser:browser.implicitly_wait(5)browser.get('file:///E:/lemon/lianxi/day33_selenuim/iframe.html')browser.find_element(By.ID, 'hello')iframe = browser.find_element(By.ID, 'i')browser.switch_to.frame(iframe)browser.find_element(By.XPATH, '//span[contains(text(),"排行榜")]')
运行结果:
例子二:
还有一种定位元素的方式:#login_container>iframe,先定位到父级,再用>连接定位子级
代码如下:
from selenium import webdriverfrom mon.by import Byclass TestDeom:def test_01(self):with webdriver.Chrome() as browser:browser.implicitly_wait(5)browser.get('/Home/User/login.html')browser.find_element(By.LINK_TEXT, '微信登录').click()iframe = browser.find_element(By.CSS_SELECTOR, '#login_container>iframe')# iframe = browser.find_element(By.XPATH, '//iframe')browser.switch_to.frame(iframe)qrcode = browser.find_element(By.CSS_SELECTOR, '.qrcode')print(f'微信二维码:{qrcode.get_attribute("src")}')
运行结果:
总结:
切换到子页面
iframe = browser.find_element(元素表达式)browser.switch_to.frame(iframe)
切换到子页面的子页面
sub_iframe = browser.find_element(元素表达式)browser.switch_to.frame(sub_iframe)
切换到父级页面
browser.switch_to.parent_frame()
切换到主页面
browser.switch_to.default_content()
3.alert切换
出现alert弹框后,再去定位主页面的元素就不管用了,所以我们要切换到alert当中,点击确定回到主页面,这样就可以定位主页面的元素了
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>py44</title></head><body><!-- 标题--><h2 id="hello" onclick="alert('are you ok?')">hello</h2></body></html>
from selenium.webdriver import Chromeclass TestAlert:def testalert(self):url = 'E:\lemon\lianxi\day33_selenuim\iframe.html'with Chrome() as browser:browser.get(url)browser.find_element('id', 'hello').click()# 注意alert是个属性,不是方法,后面没有括号browser.switch_to.alert.accept()browser.find_element('id', 'hello')
运行结果:
还有一种弹框跟alert相似,但实现方式不是原生的alert,可以直接进行元素定位
实现弹框的方式:
原生的alert,prompt,样式很丑,所以现在用的少框架vue.js实现了ui效果,弹框就是普通的元素