Selenium
1.python+Selenium案例
Selenium是一种流行的Python库用于自动化Web浏览器。它允许我们模拟用户在浏览器中的交互行为,如单击、输入文本、滚动、验证元素等。
Selenium使用选择器来定位元素,选择器是一种编写语言,用于确定要处理的元素。它们可以基于元素的标记名称、类名、属性、文本和位置等属性进行选择。
以下是一个使用Selenium进行元素定位的简单示例:
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time
# 打开浏览器
browser = webdriver.Chrome()
browser.maximize_window()
# 打开淘宝首页
browser.get('https://www.taobao.com')
# 进入登录页面
login_btn = browser.find_element_by_xpath('//*[@id="J_SiteNavLogin"]/div[1]/div[1]/a[1]')
login_btn.click()
# 进入账号密码登录页面
login_tab = browser.find_element_by_xpath('//*[@id="J_QRCodeLogin"]/div[5]/a[1]')
login_tab.click()
# 输入账号密码
username_box = browser.find_element_by_xpath('//*[@id="fm-login-id"]')
username_box.send_keys('你的淘宝账号')
password_box = browser.find_element_by_xpath('//*[@id="fm-login-password"]')
password_box.send_keys('你的淘宝密码')
# 验证码处理
captcha_box = browser.find_element_by_xpath('//*[@id="nc_1_n1z"]')
time.sleep(1)
actions = webdriver.ActionChains(browser)
actions.click_and_hold(captcha_box).move_by_offset(260, 0).release().perform()
# 点击登录
submit_btn = browser.find_element_by_xpath('//*[@id="login-form"]/div[4]/button')
submit_btn.click()
# 搜索商品
search_box = browser.find_element_by_xpath('//*[@id="q"]')
search_box.send_keys('手机')
search_box.send_keys(Keys.ENTER)
# 进入商品页面
product_box = browser.find_element_by_xpath('//*[@id="mainsrp-itemlist"]/div/div/div[1]/div[1]/div[1]/a')
product_box.click()
# 加入购物车
cart_btn = browser.find_element_by_xpath('//*[@id="J_LinkAdd"]')
cart_btn.click()
# 进入购物车页面
cart_page = browser.find_element_by_xpath('//*[@id="J_MiniCart"]/div[2]/a[1]')
cart_page.click()
# 结算
settlement_btn = browser.find_element_by_xpath('//*[@id="J_Go"]')
settlement_btn.click()
# 支付
pay_btn = browser.find_element_by_xpath('//*[@id="submitOrder_1"]/div[2]/a[1]')
pay_btn.click()
# 关闭浏览器
browser.quit()
在上面的示例中,我们使用Selenium自动进行了以下操作:
- 打开Chrome浏览器并进入淘宝首页;
- 点击登录按钮进入登录页面,并输入账号密码进行登录;
- 输入验证码,点击登录按钮进行登录;
- 在搜索框中输入商品名称并搜索;
- 进入商品页面并点击加入购物车按钮;
- 进入购物车页面并点击结算按钮;
- 进入支付页面并点击支付按钮。
当然,具体的元素定位可能需要根据网页结构进行调整,但整体流程是一致的。
代码改进:
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time
import pytest
@pytest.fixture()
def browser():
driver = webdriver.Chrome()
driver.maximize_window()
yield driver
driver.quit()
# 前置条件
def setup(browser):
browser.get('https://www.taobao.com')
time.sleep(2)
# 后置条件
def teardown(browser):
browser.quit()
# 测试用例
def test_taobao_shopping(browser):
# 进入登录页面
login_btn = browser.find_element_by_xpath('//*[@id="J_SiteNavLogin"]/div[1]/div[1]/a[1]')
login_btn.click()
time.sleep(1)
# 进入密码登录页面
login_tab = browser.find_element_by_xpath('//*[@id="J_QRCodeLogin"]/div[5]/a[1]')
login_tab.click()
time.sleep(1)
# 输入账号密码
username_box = browser.find_element_by_xpath('//*[@id="fm-login-id"]')
username_box.send_keys('你的淘宝账号')
password_box = browser.find_element_by_xpath('//*[@id="fm-login-password"]')
password_box.send_keys('你的淘宝密码')
# 验证码处理
captcha_box = browser.find_element_by_xpath('//*[@id="nc_1_n1z"]')
time.sleep(1)
actions = webdriver.ActionChains(browser)
actions.click_and_hold(captcha_box).move_by_offset(260, 0).release().perform()
# 点击登录
submit_btn = browser.find_element_by_xpath('//*[@id="login-form"]/div[4]/button')
submit_btn.click()
time.sleep(2)
# 搜索商品
search_box = browser.find_element_by_xpath('//*[@id="q"]')
search_box.send_keys('手机')
search_box.send_keys(Keys.ENTER)
time.sleep(2)
# 进入商品页面
product_box = browser.find_element_by_xpath('//*[@id="mainsrp-itemlist"]/div/div/div[1]/div[1]/div[1]/a')
product_box.click()
time.sleep(2)
# 加入购物车
cart_btn = browser.find_element_by_xpath('//*[@id="J_LinkAdd"]')
cart_btn.click()
time.sleep(2)
# 进入购物车页面
cart_page = browser.find_element_by_xpath('//*[@id="J_MiniCart"]/div[2]/a[1]')
cart_page.click()
time.sleep(2)
# 结算
settlement_btn = browser.find_element_by_xpath('//*[@id="J_Go"]')
settlement_btn.click()
time.sleep(2)
# 支付
pay_btn = browser.find_element_by_xpath('//*[@id="submitOrder_1"]/div[2]/a[1]')
pay_btn.click()
time.sleep(2)
# 断言
assert '确认收货地址' in browser.page_source
我们使用了setup和teardown来分别设置前置条件和后置条件。在测试用例中,我们根据页面中的元素进行元素定位,并执行了整个流程。在代码中,我们也为每个操作添加了时间休眠,以防止页面加载过慢导致元素无法被找到。最后,我们在测试用例中通过断言来判断支付成功后是否跳转到了确认收货地址页面。这样可以让我们更轻松地进行UI自动化测试并且可以有效避免因为页面加载问题而导致测试用例失败。
2.定位元素的方法
在Selenium中,可以使用以下方法来定位元素:
使用ID定位元素
element = driver.find_element_by_id('element_id')
使用name定位元素
element = driver.find_element_by_name('element_name')
使用link text定位元素
element = driver.find_element_by_link_text('link_text')
使用partial link text定位元素
element = driver.find_element_by_partial_link_text('partial_link_text')
使用Xpath定位元素
element = driver.find_element_by_xpath('xpath_expression')
使用CSS selector定位元素
element = driver.find_element_by_css_selector('css_selector')
其中,Xpath和CSS selector是比较常用的定位元素方式。如果需要定位多个元素,可以使用复数形式,如find_elements_by_xpath和find_elements_by_css_selector。
另外,还可以使用WebElement对象的find_element和find_elements方法来在一个元素的范围内定位子元素。
例如,对于以下HTML代码:
<div class="parent">
<span class="child">child1</span>
<span class="child">child2</span>
</div>
可以使用以下代码定位所有class为child的元素:
parent = driver.find_element_by_class_name('parent')
child_elements = parent.find_elements_by_class_name('child')
3.定位不到元素的原因
在使用Selenium定位元素时,可能会出现定位不到的情况,原因可能包括:
-
元素定位方式不正确:选择的元素定位方式不准确或者不唯一,可能会导致无法定位到元素。在这种情况下,建议使用其它的元素定位方式,或者检查页面是否发生了变化。
-
页面没有完全加载:如果页面没有完全加载,可能会导致元素定位失败。在这种情况下,可以使用显示等待或者自定义等待方式等待页面加载完毕。
-
元素不可见:如果元素在页面上不可见,它可能无法被定位到。可以使用Selenium提供的一些方法,如scrollIntoView()将元素滚动到可见区域。
-
定位元素的时间不合理:定位元素需要一定时间,过短的时间可能会导致无法定位到元素。可以增加等待时间或者使用显式等待。
-
网络问题或者浏览器驱动问题:如果网络断开或者浏览器驱动出现问题,可能会导致元素定位失败。可以检查网络连接是否正常,或者检查浏览器驱动是否正常运行。
总之,如果无法定位到元素,需要排除以上几种可能的原因,并逐一进行检查。同时,可以在代码中添加try-except语句来处理异常情况,增加程序的健壮性。
4.元素定位时间等待的几种方法
在Selenium中,强制等待、隐式等待和显式等待是三种等待页面元素的方式,它们的区别如下:
-
强制等待:使用time.sleep()方法强制等待一定时间,时间到了之后再执行后续的代码。强制等待的缺点是不管是否已经加载完成页面元素,都会等待指定的时间,如果时间设置过短,可能会导致元素还未加载完成就执行后续的操作,从而引发异常。因此,在自动化测试中,不推荐使用强制等待。
-
隐式等待:使用driver.implicitly_wait()方法设置等待时间,在等待时间内,Selenium会不断尝试查找元素,如果元素一旦被找到,则执行后续的代码。隐式等待适用于全局设置,只需要在代码中设置一次即可,在查找元素时,Selenium会自动等待一定时间,等待时间到达后,如果元素还未被加载,则抛出NoSuchElementException异常。因此,隐式等待是一种比较智能的等待方式。
-
显式等待:使用WebDriverWait()和expected_conditions类等方法来设置等待时间,直到满足特定条件后才执行后续的代码。显式等待的优点是可以根据特定的条件来等待元素的加载,如果在等待时间内元素加载完成,则继续执行后续的代码,如果等待时间到达后仍然未找到元素,则抛出TimeoutException异常。因此,显式等待是一种高效且精确的等待方式。
在使用等待机制时,推荐使用隐式等待和显式等待,尽量避免使用强制等待,因为强制等待时间的长短不好控制,容易引发异常。