高效Selenium测试技巧:轻松控制已开启的浏览器

科技   2024-10-09 16:01   广东  


👆对私有云感兴趣可以进入公众号回复“有云哦。

一、前言

在日常做Selenium测试的时候,总是遇到网页需要登录的情况,上次我们在做Selenium专题的时候,有讲过一个自动刷B站的案例,里面涉及到了登录的情况,详细推文点击这里,很多同学也提出了疑问,是否可以通过执行当前我设置好并登录好的网页去进行测试?那么我们今天就一起来探讨一些,如何连接已经打开的浏览器,并进行自动化测试。

二、控制现有浏览器的步骤解析

我们这边以Chrome浏览器为例,我们这里采用的是Chrome DevTools协议,他们为客户提供了检查和调试Chrome浏览器的便利功能。
具体步骤如下:
1、在控制台内打开Chrome浏览器的文件夹
2、在命令行中输入命令:
chrome.exe --remote-debugging-port=9222 --user-data-dir="C:\temp"
对于-remote-debugging-port参数,这里可以自由选择一个未被占用的端口号进行指定,后续在初始化Selenium连接的时候会用到该端口号。
至于--user-data-dir标志,它用于指定创建新Chrome用户数据文件夹的路径。这样做可以确保Chrome在一个新的、独立的配置文件中启动,从而避免对您的默认配置文件造成任何干扰。
3、执行完上述命令后,会生成打开一个全新的浏览器,可以在该浏览器上面进行初始化,新的用户数据也将会存在刚刚填入--user-data-dir参数的文件夹下面。
4、在进行好浏览器初始化后,在脚本中输入下述代码进行初始化,连接已开启的浏览器:
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
chrome_options = Options()
chrome_options.add_experimental_option("debuggerAddress""127.0.0.1:9222")
driver = webdriver.Chrome(chrome_options=chrome_options)
做完这一步之后,就可以直接在已打开的浏览器上执行脚本或编写脚本啦。
注意:
1、该浏览器不小心关闭后,需要再次执行第二个步骤重新打开Chrome浏览器噢。一般登录状态也会随之保留的。
2、Airtest-selenium切换新网页作用域时,使用driver.switch_to_new_tab()会出现报错:'WebDriver' object has no attribute 'switch_to_window',只需要将切换新网页作用域语句改为:driver.switch_to.window(driver.window_handles[-1])即可。

三、代码案例

通过上述所讲的接管已开启浏览器的方式,我们将之前刷B站的代码重新修改一下,去掉了登录并存储cookie的方法,直接通过连接我们已打开登录好账号的浏览器,执行一系列的刷B站操作,如搜索、点击播放、发送弹幕等。
参考代码:
# 引入seleniumwebdriver模块和其他必要的库
from airtest.core.api import *
from airtest_selenium.proxy import WebChrome
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.chrome.options import Options
from selenium import webdriver
import threading
import time
import random
import json

# 设置Chrome选项,连接到已打开的Chrome浏览器
chrome_options = Options()
chrome_options.add_experimental_option("debuggerAddress""127.0.0.1:9222")
driver.implicitly_wait(20)

# 连接到已打开的Chrome浏览器
driver = webdriver.Chrome(options=chrome_options)

print(driver.title)

#打开chrome浏览器并打开视频播放
def start_selenium():
    # 输入搜索关键词并提交搜索
    search_box = driver.find_element(By.CLASS_NAME,'nav-search-input')
    search_box.send_keys('Airtest')
    
    driver.switch_to.window(driver.window_handles[-1])  # 切换界面
    sleep(3)

    #点击进入“Airtest酱”主页
    driver.find_element(By.XPATH,"//*[@id=\"i_cecream\"]/div/div[2]/div[2]/div/div/div/div[2]/div/div/div/div/div/div/h2/a").click()
    
    # 再次切换到新打开的标签页并刷新页面
    driver.switch_to.window(driver.window_handles[-1]) 
    driver.refresh()
       
    sleep(2)
    # 查找特定视频元素
    video_ele = driver.find_element(By.XPATH,"//div[@title='14Airtest自动化测试小白课程']")

    # 滚动到该视频元素位置并点击
    driver.execute_script("arguments[0].scrollIntoView(true);", video_ele)
    sleep(5)
    video_ele.click()

    # 获取所有视频列表
    video_list = driver.find_elements(By.XPATH,"//ul[@class='row video-list clearfix']//a[@class='title']")

    # 随机选择一个视频并点击播放
    random_element = random.choice(video_list)
    random_element.click()

    # 切换到新打开的视频页面
    driver.switch_to.window(driver.window_handles[-1])

    # 暂停或播放视频
    random_element.click()  # 随机播放一个视频
    driver.switch_to.window(driver.window_handles[-1])  # 切换界面


#暂停播放
def video_pause_and_play(check_btn=False):
    
    try:
        # 查找播放/暂停按钮
        paus_btn = driver.find_elements(By.XPATH,
            "//*[@id=\"bilibili-player\"]//div[@class='bpx-player-ctrl-btn bpx-player-ctrl-play']")
        if paus_btn[0]:
            # 获取初始时间
            detection_time1 = driver.find_elements(By.XPATH,
                '//*[@class="bpx-player-control-bottom-left"]//div[@class="bpx-player-ctrl-time-label"]')
            start_time = detection_time1[0].text
            sleep(5)

            # 时间戳检测是否在播放
            detection_time2 = driver.find_elements(By.XPATH,
                '//*[@class="bpx-player-control-bottom-left"]//div[@class="bpx-player-ctrl-time-label"]')
            end_time = detection_time2[0].text
            
            # 如果时间没变或check_btnTrue,则点击播放/暂停按钮
            if start_time == end_time or check_btn:
                print("点击播放(暂停)按钮")
                paus_btn[0].click()
    except Exception as e:
        print(f"点击播放(暂停)出错{e}")

#发送弹幕
def video_sms(sms_body="不错"):
    try:
        # 查找弹幕输入框
        sms_input_edit = driver.find_element(By.XPATH,"//input[@class='bpx-player-dm-input']")
        # 输入弹幕内容并发送
        sms_input_edit.send_keys(sms_body)
        sms_input_edit.send_keys(Keys.ENTER)
    except Exception as e:
        print(f"发弹幕出错{e}")
    print(f"发送弹幕:{sms_body}")

# 点赞视频
def video_love():
    
    print("点赞")
    try:
        # 查找点赞按钮
        sms_input_edit = driver.find_elements(By.XPATH,
            "//div[@class='toolbar-left-item-wrap']//div[@class='video-like video-toolbar-left-item']")
        if not sms_input_edit:
            print("已经点赞")
            return
        # 点击点赞按钮
        sms_input_edit[0].click()
    except Exception as e:
        print(f"点赞出错{e}")

# 收藏视频
def video_collect():

    print("收藏")
    try:
        # 查找收藏按钮
        colle_btn = driver.find_elements(By.XPATH,
            "//div[@class='toolbar-left-item-wrap']//div[@class='video-fav video-toolbar-left-item']")
        if not colle_btn:
            print("已经收藏")
            return
        # 点击收藏按钮
        colle_btn[0].click()
        sleep(2)
        # 获取收藏夹列表
        list_coll = driver.find_elements(By.XPATH,"//div[@class='group-list']//ul/li/label")

        # 随机选择一个收藏夹
        random_element = random.choice(list_coll)
        
        # 滚动到选中的收藏夹元素位置
        random_element = random.choice(list_coll)  # 随机收藏
        # 滚动到指定元素处
        driver.execute_script("arguments[0].scrollIntoView(true);", random_element)
        sleep(2)
        random_element.click()  # 随机收藏一个
        
        sleep(2)
        # 点击确认收藏按钮
        driver.find_element(By.XPATH,"//div/button[@class='btn submit-move']").click()
        
    except Exception as e:
        print(f"收藏出错{e}")

def wait_for_element(driver, selector, timeout=60 * 5):
    try:
        # 使用WebDriverWait等待元素出现
        element = WebDriverWait(driver, timeout).until(
            EC.presence_of_element_located((By.XPATH, selector))
        )
    except Exception:
        print("元素未出现")
        return None

#头像元素初始化
selem = "//div[@class='bili-header fixed-header']//*[contains(@class, 'header-avatar-wrap--container mini-avatar--init')]"

if __name__ == "__main__":
    # 启动浏览器并打开视频
    start_selenium()

    # 等待元素出现
    element = wait_for_element(driver, selem)
    if element:
        print("检测到已经登录")

        # 执行暂停和播放操作
        for _ in range(2):
            video_pause_and_play()
            sleep(3)
        # 刷新页面
        driver.refresh()

        # 发送多条随机弹幕
        sms_list = ["感觉不错,收藏了""666,这么强""自动化还得看airtest""干货呀""麦克阿瑟直呼内行"]
        for item in sms_list:
            wait_time = random.randint(510)  # 随机等待5-10
            time.sleep(wait_time)
            video_sms(item)  # 发送弹幕

        # 点赞和收藏视频
        for action in [video_love, video_collect]:
            action()
            sleep(3)
    else:
        print("登录超时")

四、小结

本周我们一起探讨了如何让selenium连接已开启的浏览器,通过Chrome DevTools协议,创建新的浏览器缓存,在该浏览器上提前做好对应的设置以及登录好对应的账号,就可以通过端口号可以连接到对应的浏览器上。大家也可以通过这个方式,随时在已开启的浏览器上进行调试,同时,我们也非常欢迎同学们能够提供自己在常用场景实现的代码。
如果大家在使用过程中有一些新的使用方式或者遇到了问题,又或者有任何想要深入了解的知识点,欢迎在官方交流群(526033840)里告诉我们或者提交issue。
(猜你还想看
【IOS自动化】IOS18如何使用Airtest进行自动化测试及go-ios的基本使用
【私有云场景案例分享③】批量回归测试自动化流程
【装包测试】Android应用权限授权小技巧

AirtestProject
AirtestProject是网易开源的UI自动化测试方案。关注我们,获取测试领域的最新技术,洞察测试行业的最新动态。
 最新文章