生活札记

Python + Selenium Web之自动化测试(二)

copylian    1 评论    14293 浏览    2023.03.19

一、Selenium简介

Selenium 是一个用于Web应用程序测试的工具。Selenium测试直接运行在浏览器中,就像真正的用户在操作一样。支持的浏览器包括IE(7, 8, 9, 10, 11),Mozilla Firefox,Safari,Google Chrome,Opera等。这个工具的主要功能包括:测试与浏览器的兼容性——测试你的应用程序看是否能够很好得工作在不同浏览器和操作系统之上。测试系统功能——创建回归测试检验软件功能和用户需求。支持自动录制动作和自动生成 .Net、Java、Perl等不同语言的测试脚本。

tut_20200504110845_36.png

我们在这里使用 Selenium with Python 版本,主要用来模拟用户在网站上的操作和请求,以便于我们能更好的进行爬虫获取数据。

教程:https://www.bilibili.com/video/BV1Z4411o7TA/

文档:https://www.byhy.net/tut/auto/selenium/01/

注:如果Python的输出窗口中文乱码,则需要配置环境变量,PYTHONIOENCODING = utf-8

微信图片_20230331105127.png

二、安装

1)、安装Python的selenium插件

pip install selenium

2)、下载Google浏览器驱动插件

插件地址:https://chromedriver.storage.googleapis.com/index.html,选中与当前浏览器大版本相同的文件。

微信图片_20230323162529.png

微信图片_20230323160335.png

下载chromedriver_win32.zip,解压到:D:\Tools\chromedriver.exe,将目录加到环境变量path里。

微信图片_20230323160710.png

三、应用

1)、Demo案例

代码:

        # Demo案例

        from selenium import webdriver

        from selenium.webdriver.chrome.service import Service

        

        # 加上参数,禁止 chromedriver 日志写屏

        options = webdriver.ChromeOptions()

        options.add_experimental_option(

                'excludeSwitches', ['enable-logging']

        )

        

        # 创建 WebDriver 对象,指明使用chrome浏览器驱动

        # wd = webdriver.Chrome(r'D:\Tools\chromedriver.exe')

        # wd = webdriver.Chrome(service=Service(r'D:\Tools\chromedriver.exe'))

        

        # 将可执行文件放入环境变量path中

        wd = webdriver.Chrome(options=options)

        

        # 调用WebDriver 对象的get方法 可以让浏览器打开指定网址

        wd.get("https://www.copylian.com")

        

        # 不断开

        input()


执行:py selenium1.py

微信图片_20230323161832.png

微信图片_20230323162651.png

2)、选择元素:css选择器

代码:

        # 选择元素

        from selenium import webdriver

        from selenium.webdriver.common.by import By

        import time

        

        # 实例化

        wd = webdriver.Chrome()

        

        # implicitly_wait:可以称之为隐式等待或者全局等待,如果找不到元素,每隔半秒钟再去界面上查看一次,直到找到该元素或者过了10秒最大时长

        # 获取在中间使用time.sleep(1)也可以

        wd.implicitly_wait(10)

        

        # 访问URL

        wd.get("https://www.copylian.com")

        

        # 获取ID元素

        # searchButton = wd.find_element(By.ID, "search-trigger")

        

        # 获取CLASS元素

        # searchButton = wd.find_element(By.CLASS_NAME, "search-trigger-a")

        

        # 获取TAG_NAME

        # searchButton = wd.find_element(By.TAG_NAME, "a")

        

        # 获取选择器CSS_SELECTOR元素

        searchButton = wd.find_element(By.CSS_SELECTOR, "#search-trigger .search-trigger-a")

        searchButton.click()

        

        # 获取ID元素

        searchKey = wd.find_element(By.ID, "search-key")

        searchKey.send_keys("k8s")

        

        # 获取ID元素

        goSearch = wd.find_element(By.ID, "go-search")

        goSearch.click()

        

        # 输入

        input()


3)、操作元素:css获取值

代码:

        # 操作元素

        from selenium import webdriver

        from selenium.webdriver.common.by import By

        import time

        

        # 实例化

        wd = webdriver.Chrome()

        

        # implicitly_wait:可以称之为隐式等待或者全局等待,如果找不到元素,每隔半秒钟再去界面上查看一次,直到找到该元素或者过了10秒最大时长

        # 获取在中间使用time.sleep(1)也可以

        wd.implicitly_wait(10)

        

        # 访问URL

        wd.get("https://www.copylian.com")

        

        # 选择元素

        h2 = wd.find_element(By.CSS_SELECTOR, ".welcome-text h2")

        

        # 获取值

        print(h2.text)

        print("innerText: "+h2.get_attribute("innerText"))

        print("textContent: "+h2.get_attribute("textContent"))

        

        # 获取属性

        h2_class = h2.get_attribute("class")

        print("class: "+h2_class)

        

        # 获取outerHTML

        h2_outerHTML = h2.get_attribute("outerHTML")

        print("outerHTML: "+h2_outerHTML)

        

        # 获取innerHTML

        h2_innerHTML = h2.get_attribute("innerHTML")

        print("innerHTML: "+h2_innerHTML)

        

        # 选择多个元素

        # h2 = wd.find_elements(By.CSS_SELECTOR, ".welcome-text h2")

        # for i in h2:

        #     print(i.text)

        

        # 选中输入框

        # 获取选择器CSS_SELECTOR元素

        searchButton = wd.find_element(By.ID, "search-trigger")

        searchButton.click()

        

        # 获取ID元素

        searchKey = wd.find_element(By.ID, "search-key")

        searchKey.send_keys("k8s") # 文本输入

        searchKey.clear() # 清空

        searchKey.send_keys("jenkins")

        print("input value: "+searchKey.get_attribute("value"))

        

        # 输入

        input()


4)、CSS表达式:

直接子元素选择器:#myId > span

属性选择器:a[href="https://www.copylian.com"]、.className[href="https://www.copylian.com"]、a[href*="miitbeian"]、a[href^="http"]、a[href$="gov.cn"]

组选择器(逗号隔开):.plant,.animal

父元素的第n个子节点:p:nth-child(n)

父元素的倒数第n个子节点:p:nth-last-child(n)

父元素的第几个某类型的子节点:p:nth-of-type(n)

父元素的倒数第几个某类型的子节点:p:nth-last-of-type(n)

奇数节点和偶数节点:p:nth-child(odd)、p:nth-child(even)

相邻兄弟节点选择:h3 + span

后续所有兄弟节点选择:h3 ~ span

注:Google浏览器F12开发者工具栏,在html中Ctrl+F可以直接通过选择器查找

微信图片_20230324165326.png

5)、切换frame:switch_to.frame() 切换到iframeswitch_to.default_content() 切换到默认

代码:

        # 切换frame

        from selenium import webdriver

        from selenium.webdriver.common.by import By

        

        # 实例化

        wd = webdriver.Chrome()

        

        # implicitly_wait:可以称之为隐式等待或者全局等待,如果找不到元素,每隔半秒钟再去界面上查看一次,直到找到该元素或者过了10秒最大时长

        # 获取在中间使用time.sleep(1)也可以

        wd.implicitly_wait(10)

        

        # 访问URL

        wd.get("https://cdn2.byhy.net/files/selenium/sample2.html")

        

        # 通过对象进入frame

        # frame = wd.find_element(By.ID, "frame1")

        # wd.switch_to.frame(frame)

        

        # 通过ID

        # wd.switch_to.frame("frame1")

        

        # 通过name名称

        wd.switch_to.frame("innerFrame")

        

        # 获取title

        element = wd.find_element(By.TAG_NAME, "title")

        print(element.get_attribute("innerText"))

        

        # 切换回到默认的frame

        wd.switch_to.default_content()

        element1 = wd.find_element(By.TAG_NAME, "title")

        print(element1.get_attribute("innerText"))

        

        # 输入

        input()

微信图片_20230325212226.png

6)、切换窗口:switch_to.window() 切换到窗口、wd.window_handles 获取所有的窗口、wd.current_window_handle 获取当前窗口

代码:

        # 切换窗口

        from selenium import webdriver

        from selenium.webdriver.common.by import By

        

        # 实例化

        wd = webdriver.Chrome()

        

        # implicitly_wait:可以称之为隐式等待或者全局等待,如果找不到元素,每隔半秒钟再去界面上查看一次,直到找到该元素或者过了10秒最大时长

        # 获取在中间使用time.sleep(1)也可以

        wd.implicitly_wait(10)

        

        # 访问URL

        wd.get("https://www.copylian.com")

        

        # 选中输入框

        # 获取选择器CSS_SELECTOR元素

        searchButton = wd.find_element(By.ID, "search-trigger")

        searchButton.click()

        

        # 获取ID元素

        searchKey = wd.find_element(By.ID, "search-key")

        searchKey.send_keys("jenkins")

        

        # 获取ID元素

        goSearch = wd.find_element(By.ID, "go-search")

        goSearch.click()

        

        # 获取当前窗口

        current_handle = wd.current_window_handle

        

        # 获取浏览器打开的窗口

        for handle in wd.window_handles:

            # 切换窗口

            wd.switch_to.window(handle)

            if "jenkins" in wd.title:

                break

        

        # 对应窗口

        print(wd.title)

        

        # 切换回当前窗口

        wd.switch_to.window(current_handle)

        print(wd.title)

        

        # 输入

        input()

微信图片_20230325212200.png

7)、选择框:select_by_visible_text()、select_by_value()、select_by_index()、deselect_by_visible_text()、deselect_by_value()、deselect_by_index()、deselect_all()、options、all_selected_options

代码:

        # 选择框

        from selenium import webdriver

        from selenium.webdriver.common.by import By

        from selenium.webdriver.support.ui import Select

        

        # 实例化

        wd = webdriver.Chrome()

        

        # implicitly_wait:可以称之为隐式等待或者全局等待,如果找不到元素,每隔半秒钟再去界面上查看一次,直到找到该元素或者过了10秒最大时长

        # 获取在中间使用time.sleep(1)也可以

        wd.implicitly_wait(10)

        

        # 访问URL

        wd.get("https://cdn2.byhy.net/files/selenium/test2.html")

        

        # radio单选框

        radio = wd.find_element(By.CSS_SELECTOR, "#s_radio input[name='teacher']:checked")

        print(radio.get_attribute("value"))

        

        radio1 = wd.find_element(By.CSS_SELECTOR, "#s_radio input[value='小江老师']")

        radio1.click()

        

        # checkbox复选框

        checkboxs = wd.find_elements(By.CSS_SELECTOR, "#s_checkbox input[name='teacher']:checked")

        for checkbox in checkboxs:

            print(checkbox.get_attribute("value"))

            # 选中的全部设置为未选中

            checkbox.click()

        

        checkbox1 = wd.find_element(By.CSS_SELECTOR, "#s_checkbox input[value='小江老师']")

        checkbox2 = wd.find_element(By.CSS_SELECTOR, "#s_checkbox input[value='小雷老师']")

        checkbox1.click()

        checkbox2.click()

        

        # select 单选框

        selectSingle = Select(wd.find_element(By.ID, "ss_single"))

        # selectSingle.select_by_visible_text("小雷老师") # 显示的值

        # selectSingle.select_by_value("小江老师") # 隐藏的值

        selectSingle.select_by_index(1) # 索引序号,0开始

        print(selectSingle.options) # 选项

        

        # select 多选框

        selectMulti = Select(wd.find_element(By.ID, "ss_multi"))

        # selectMulti.deselect_all() # 取消所有选中

        selectMulti.select_by_index(0)

        selectMulti.select_by_index(1)

        selectMulti.select_by_index(2)

        # selectMulti.deselect_by_index(1)  # 索引序号,0开始去除选中

        selectMulti.deselect_by_value("小雷老师")

        selectMulti.deselect_by_visible_text("小江老师")

        print(selectMulti.options) # 选项

        print(selectMulti.all_selected_options) # 所有选中的项

        

        # 输入

        input()


8)、行为动作ActionChains()、执行JavaScript(execute_script)浏览器原生对话框(alertconfirmprompt)、当前标题、当前url、截屏、上传文件、手机模式:

代码:

        # 其他更多

        from selenium import webdriver

        from selenium.webdriver.common.by import By

        from selenium.webdriver.support.ui import Select

        from selenium.webdriver.common.action_chains import ActionChains

        

        # 手机模式

        mobile_emulation = {"deviceName": "Nexus 5"}

        chrome_options = webdriver.ChromeOptions()

        chrome_options.add_experimental_option("mobileEmulation", mobile_emulation)

        wd = webdriver.Chrome(desired_capabilities=chrome_options.to_capabilities())

        

        # 实例化

        wd = webdriver.Chrome()

        

        # implicitly_wait:可以称之为隐式等待或者全局等待,如果找不到元素,每隔半秒钟再去界面上查看一次,直到找到该元素或者过了10秒最大时长

        # 获取在中间使用time.sleep(1)也可以

        wd.implicitly_wait(10)

        

        # 访问URL

        wd.get("https://www.baidu.com/")

        

        # 实例化动作

        ac = ActionChains(wd)

        

        # 执行JavaScript

        wd.execute_script(

            """

            setTimeout(function(){debugger}, 5000)

            """

        )

        

        # 冻结界面

        # setTimeout(function(){debugger}, 5000)

        # debugger

        

        # 鼠标移动到更多按钮

        more = wd.find_element(By.CSS_SELECTOR, "div.s-top-more-btn")

        ac.move_to_element(more).perform()

        

        # 当前标题

        print(wd.title)

        

        # 当前url

        print(wd.current_url)

        

        # 获取窗口大小

        print(wd.get_window_size())

        

        # 设置窗口大小

        wd.set_window_size(900,1000)

        

        # 截屏

        wd.get_screenshot_as_file("1.png")

        wd.get_screenshot_as_file("2.png")

        wd.get_screenshot_as_file("F:\\1.png")

        print(wd.get_screenshot_as_png())

        print(wd.get_screenshot_as_base64())

        

        # 上传文件

        wd.get("https://tinypng.com/")

        ele = wd.find_element(By.CSS_SELECTOR, 'input[type=file]')

        ele.send_keys(r'F:\\wnmp\\wwwgit\\fiddler\\1.png')

        ele.send_keys(r'F:\\wnmp\\wwwgit\\fiddler\\2.png')

        

        # alter弹窗

        wd.get("https://cdn2.byhy.net/files/selenium/test4.html")

        alertElement = wd.find_element(By.ID, "b1")

        alertElement.click()

        alert = wd.switch_to.alert

        print(alert.text) # 值

        alert.accept() # 点击确定按钮

        

        # confirm弹窗

        confirm = wd.find_element(By.ID, "b2")

        confirm.click()

        alert = wd.switch_to.alert

        print(alert.text) # 值

        alert.accept()  # 点击确定按钮

        alert.dismiss()  # 点击取消按钮

        

        # prompt弹窗

        prompt = wd.find_element(By.ID, "b3")

        prompt.click()

        alter = wd.switch_to.alert

        print(alter.text) # 值

        alter.send_keys("prompt的值") # 设置prompt的值

        alter.accept()  # 点击确定按钮

        alter.dismiss()  # 点击取消按钮

        

        # 输入

        input()


四、xpath:XPath (XML Path Language) 是由国际标准化组织W3C指定的,用来在 XML 和 HTML 文档中选择节点的语言。有些场景 用 css 选择web 元素 很麻烦,而xpath 却比较方便。另外 Xpath 还有其他领域会使用到,比如 爬虫框架 Scrapy, 手机App框架 Appium

代码:

        # xpath

        from selenium import webdriver

        from selenium.webdriver.common.by import By

        

        # 实例化

        wd = webdriver.Chrome()

        

        # implicitly_wait:可以称之为隐式等待或者全局等待,如果找不到元素,每隔半秒钟再去界面上查看一次,直到找到该元素或者过了10秒最大时长

        # 获取在中间使用time.sleep(1)也可以

        wd.implicitly_wait(10)

        

        # 访问URL

        wd.get("https://cdn2.byhy.net/files/selenium/test1.html")

        

        # xpath绝对路径 /

        title = wd.find_element(By.XPATH, "/html/head/title") # 相当于 html > head > title

        print(title.get_attribute("innerText"))

        

        # xpath相对路径 //

        divP = wd.find_element(By.XPATH, "//div//p") # 相当于 div p

        print(divP.get_attribute("innerText"))

        

        # xpath通配符 *

        select = wd.find_element(By.XPATH, "//select/*")  # div里所有元素

        print(select.get_attribute("innerText"))

        

        # xpath属性选择 [@属性名='属性值']

        multiChoice = wd.find_element(By.XPATH, "//*[@class='multi_choice']") # class属性

        print(multiChoice.get_attribute("innerHTML"))

        

        # xpath属性值包含字符串 contains、starts-with

        multiChoice1 = wd.find_element(By.XPATH, "//*[contains(@class,'multi')]") # 属性class包含multi

        print(multiChoice1.get_attribute("innerHTML"))

        

        multiChoice2 = wd.find_element(By.XPATH, "//select[starts-with(@class,'multi')]") # 属性class以multi开头

        print(multiChoice2.get_attribute("innerHTML"))

        

        # xpath获取子元素 [n]

        divP2 = wd.find_element(By.XPATH, "//div/*[2]")  # div下所以元素的第二个子元素

        print(divP2.get_attribute("innerHTML"))

        

        # xpath倒数获取子元素 [last()-n]

        divP3 = wd.find_element(By.XPATH, "//div/*[last()-2]") # div下所以元素的倒数第三个子元素

        print(divP3.get_attribute("innerHTML"))

        

        # xpath范围选择 position()

        divP4 = wd.find_element(By.XPATH, "//div/p[position() >= last()]")  # div下位置 >= last()+1的元素

        print(divP4.get_attribute("innerHTML"))

        

        # xpath 组选择 |

        selectOr = wd.find_element(By.XPATH, "//*[@class='single_choice'] | //*[@class='multi_choice']") # 或者关系

        print(selectOr.get_attribute("innerHTML"))

        

        # xpath 父节点 /..

        parent = wd.find_element(By.XPATH, "//*[@class='single_choice']/..") # 父节点

        print(parent.get_attribute("innerHTML"))

        

        # xpath 兄弟节点 following-sibling::*[n] - 后面兄弟节点、preceding-sibling::*[n] - 前面兄弟节点

        following = wd.find_element(By.XPATH, "//*[@class='single_choice']/following-sibling::h4") # 后面兄弟节点

        print(following.get_attribute("innerHTML"))

        

        preceding = wd.find_element(By.XPATH, "//*[@class='single_choice']/preceding-sibling::*[1]") # 前面兄弟节点

        print(preceding.get_attribute("innerHTML"))


        # xpath 查找当前节点后的元素 .//p

        china = wd.find_element(By.ID, 'china')

        elements = china.find_elements(By.XPATH, './/p')


        # 退出

        wd.quit()

只袄早~~~
感谢你的支持,我会继续努力!
扫码打赏,感谢您的支持!

文明上网理性发言!