什么是Selenium?

Selenium是一个开源的Web应用程序测试框架,它可以使用多种编程语言(包括Python)来模拟用户与浏览器的交互。它提供了丰富的功能,包括启动浏览器会话、导航到URL、查找和操作页面元素等。

安装与配置

在使用Selenium之前,我们需要保证正确安装和配置所需的软件和驱动程序。以下是必要的步骤:

  1. 安装Python:由于Selenium是一个Python模块,首先需要安装Python。您可以从Python官方网站下载并安装适合您操作系统的版本。

  2. 安装Selenium模块:使用Python的包管理器(如pip)安装Selenium模块。在命令行中执行以下命令:

    1
    pip install selenium
  3. 下载浏览器驱动程序:为了使用Selenium控制浏览器,我们需要下载相应的浏览器驱动程序,并将其添加到系统的PATH环境变量中。以下是常用浏览器驱动程序的下载链接:

    注意:下载相应版本的驱动程序,并确保与所使用的浏览器版本匹配。

  4. 配置Selenium使用的浏览器驱动程序:在Python代码中,我们需要指定Selenium使用哪个浏览器驱动程序。以下是一个示例代码,展示如何配置Chrome浏览器驱动程序:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    from selenium import webdriver

    # 指定Chrome驱动程序路径
    chromedriver_path = r"C:\Users\Administrator\AppData\Local\Google\Chrome\Application\chromedriver.exe"
    # 启动浏览器
    driver = webdriver.Chrome()
    # 窗口最大化
    driver.maximize_window()
    # 访问网址
    driver.get("https://baidu.com/")

    注意:请根据实际驱动程序的路径进行配置。

常用方法举例

查找页面元素

1
2
3
4
5
6
7
8
9
# 通过XPath查找元素
input_element = driver.find_element_by_xpath('//*[@id="kw"]')
# 通过CSS Selector查找元素
button = driver.find_element_by_css_selector('#su')
# 通过class查找元素
# 如果class中带空格请切换其他方式 或者 选择唯一的class
button1 = driver.find_element_by_class_name('s_btn')
# 通过ID查找元素
button2 = driver.find_element_by_id('su')

操作页面元素

1
2
3
4
5
6
7
8
9
10
11
input_element = driver.find_element_by_xpath('//*[@id="kw"]')
# 操作输入框并输入文字
input_element.send_keys('Python')

# 模拟键盘操作(按下回车键)
# from selenium.webdriver.common.keys import Keys
# input_element.send_keys(Keys.ENTER)

button = driver.find_element_by_css_selector('#su')
# 点击按钮
button.click()

等待页面加载

在Selenium中,等待网页加载完成是非常重要的,以确保在执行后续操作之前,页面的所有元素已经完全加载。以下是几种常用的等待网页加载的处理方式:

  1. 强制等待:

    1
    2
    3
    import time

    time.sleep(5) # 等待5秒钟

    这种方式是最简单粗暴的等待方式,但不推荐在实际使用中过多地使用,因为它没有考虑到页面加载速度的变化和异步加载的情况。

  2. 隐式等待:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    import time

    from selenium import webdriver

    formatted_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
    print("程序开始执行:", formatted_time)
    driver = webdriver.Chrome()
    driver.get("https://www.cheneyblog.com")
    formatted_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
    print("隐士等待开始:", formatted_time)
    driver.implicitly_wait(10) # 设置隐式等待时间为10秒
    driver.maximize_window()
    driver.find_element_by_xpath('//*[@id="blog-info"]/a/img')
    formatted_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
    print("找到对于标签:", formatted_time)
    driver.close()
    formatted_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
    print("程序结束:", formatted_time)

    隐式等待会在查找元素时等待一定的时间,如果元素存在则立即返回,如果超过了设定的等待时间,仍没有找到元素,则会抛出异常。
    缺点:一旦设置了隐式等待,则它存在整个 WebDriver 对象实例的声明周期中,它将会在寻找每个element的时候都进行等待,这样会增加整个测试执行的时间。

  3. 显式等待:

    显式等待是一种更灵活、更高级的等待方式,可以在指定条件满足或超时之前持续等待。它使用 ExpectedConditions 类来定义等待条件。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    import time

    from selenium import webdriver
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.support import expected_conditions as EC

    formatted_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
    print("程序开始执行:", formatted_time)
    driver = webdriver.Chrome()
    driver.get("https://www.cheneyblog.com")
    formatted_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
    print("显示等待开始:", formatted_time)
    # 设置最长等待时间为10秒
    wait = WebDriverWait(driver, 10)
    driver.maximize_window()
    # 等待元素可见
    element = wait.until(EC.visibility_of_element_located((By.XPATH, '//*[@id="blog-info"]/a/img')))
    formatted_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
    print("找到对于标签:", formatted_time)
    driver.close()
    formatted_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
    print("程序结束:", formatted_time)

    在上面的代码中,我们使用 WebDriverWait 类来指定等待时间,并将其传递给 until 方法。在 until 方法中,我们使用 ExpectedConditions 类中的 visibility_of_element_located 方法来定义等待条件,即等待元素可见。

    使用显式等待可以进行更精细的控制,例如等待元素可用、可点击、存在等等,可以根据项目需求进行灵活设置。

    | 条件名称 | 描述 |
    |—————————-|——————————————————————|
    | title_is | 根据页面的标题判断等待条件是否成立。 |
    | title_contains | 根据页面的标题是否包含指定的字符串判断等待条件是否成立。 |
    | presence_of_element_located | 根据元素定位器是否在DOM中出现判断等待条件是否成立。 |
    | visibility_of_element_located | 根据元素定位器是否在DOM中可见判断等待条件是否成立。 |
    | visibility_of | 根据元素是否可见判断等待条件是否成立。 |
    | text_to_be_present_in_element | 根据元素中是否包含指定文本判断等待条件是否成立。 |
    | text_to_be_present_in_element_value | 根据元素的value属性中是否包含指定文本判断等待条件是否成立。 |
    | frame_to_be_available_and_switch_to_it | 根据frame是否可用判断等待条件是否成立,并在切换到frame。 |
    | element_to_be_clickable | 根据元素是否可点击判断等待条件是否成立。 |
    | element_selection_state_to_be | 根据元素选择状态是否满足指定条件判断等待条件是否成立。 |
    | element_located_selection_state_to_be | 根据元素选择状态是否满足指定条件判断等待条件是否成立。 |
    | alert_is_present | 判断页面上是否存在alert弹窗。 |

这些判断条件可以根据实际需求来选择使用,例如等待页面标题、元素的出现、元素可见性、元素文本包含等等。通过合理使用这些等待条件,可以确保在执行后续操作之前,页面或元素已经加载或满足特定条件,提高测试或自动化任务的稳定性和准确性。

所有等待都是等页面加载完成(浏览器标签左上角圈圈不再转)才开始执行,当页面某些 js无法加载,但是想找的element已经出来了,它还是不会执行下面的代码,直到页面加载完成,才会执行等待。

标签页切换

1. 获取当前窗口句柄

在切换标签页之前,首先需要获取当前窗口的句柄,也就是窗口的唯一标识。可以通过current_window_handle属性来获取当前窗口句柄:

1
current_window_handle = driver.current_window_handle

2. 打开新的标签页

可以通过执行JavaScript来实现在新标签页中打开一个链接:

1
driver.execute_script("window.open('http://www.example.com','_blank');")

3. 切换到新打开的窗口

1
2
3
4
5
6
# 获取所有窗口句柄
all_window_handles = driver.window_handles

# 切换到新打开的窗口
new_window_handle = [handle for handle in all_window_handles if handle != current_window_handle][0]
driver.switch_to.window(new_window_handle)

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

driver = webdriver.Chrome()
# 打开百度
driver.get("https://www.baidu.com")
# 获取百度窗口的句柄
current_window_handle = driver.current_window_handle
# 新的标签页中打开淘宝
driver.execute_script("window.open('http://www.taobao.com','_blank');")
# 获取所有窗口句柄
all_window_handles = driver.window_handles
# 切换到淘宝窗口
new_window_handle = [handle for handle in all_window_handles if handle != current_window_handle][0]
driver.switch_to.window(new_window_handle)

input_element = WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.XPATH, '//*[@id="q"]')))
# 操作输入框并输入文字
input_element.send_keys('键盘')

button = driver.find_element_by_css_selector('#J_TSearchForm > div.search-button > button')
# 点击搜索
button.click()

在这个示例中,我们首先打开百度页面并获取当前窗口句柄,然后在新的标签页中打开淘宝页面,接着切换到新打开的淘宝标签页,并在淘宝标签页中搜索键盘。