生活札记
Python + Selenium Web之自动化测试(二)
一、Selenium简介
Selenium 是一个用于Web应用程序测试的工具。Selenium测试直接运行在浏览器中,就像真正的用户在操作一样。支持的浏览器包括IE(7, 8, 9, 10, 11),Mozilla Firefox,Safari,Google Chrome,Opera等。这个工具的主要功能包括:测试与浏览器的兼容性——测试你的应用程序看是否能够很好得工作在不同浏览器和操作系统之上。测试系统功能——创建回归测试检验软件功能和用户需求。支持自动录制动作和自动生成 .Net、Java、Perl等不同语言的测试脚本。
我们在这里使用 Selenium with Python 版本,主要用来模拟用户在网站上的操作和请求,以便于我们能更好的进行爬虫获取数据。
教程:https://www.bilibili.com/video/BV1Z4411o7TA/
文档:https://www.byhy.net/tut/auto/selenium/01/
注:如果Python的输出窗口中文乱码,则需要配置环境变量,PYTHONIOENCODING = utf-8
二、安装
1)、安装Python的selenium插件
pip install selenium
2)、下载Google浏览器驱动插件
插件地址:https://chromedriver.storage.googleapis.com/index.html,选中与当前浏览器大版本相同的文件。
下载chromedriver_win32.zip,解压到:D:\Tools\chromedriver.exe,将目录加到环境变量path里。
三、应用
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
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可以直接通过选择器查找
5)、切换frame:switch_to.frame() 切换到iframe、switch_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()
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()
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)浏览器原生对话框(alert、confirm、prompt)、当前标题、当前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()
文明上网理性发言!
已完结!