圆弧派博客 - 专注于网络技术 - 教程
https://www.iarc.top/tag/%E6%95%99%E7%A8%8B/
-
Selenium常用代码速查手册
https://www.iarc.top/515.html
2025-11-27T10:42:00+08:00
Selenium常用代码速查手册1. 基础配置用法:导入必要的模块,初始化浏览器驱动from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver import ActionChains, Keys
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from time import sleep
# 初始化Chrome浏览器(需要先下载chromedriver)
driver = webdriver.Chrome()
driver.maximize_window() # 最大化窗口
driver.implicitly_wait(10) # 设置隐式等待10秒
# 打开网页
driver.get("https://www.baidu.com")2. 元素定位用法:在网页中找到你要操作的元素(按钮、输入框等)# CSS选择器(推荐使用,最灵活)
element = driver.find_element(By.CSS_SELECTOR, "#id") # 通过id找元素
element = driver.find_element(By.CSS_SELECTOR, ".class") # 通过class找元素
element = driver.find_element(By.CSS_SELECTOR, "input[type='text']") # 通过属性找元素
# 其他定位方式
element = driver.find_element(By.ID, "element_id") # 直接通过id找
element = driver.find_element(By.CLASS_NAME, "class_name") # 通过class名找
element = driver.find_element(By.XPATH, "//div[@class='example']") # 通过xpath找
element = driver.find_element(By.TAG_NAME, "button") # 通过标签名找
element = driver.find_element(By.LINK_TEXT, "链接文本") # 通过链接文字找
element = driver.find_element(By.PARTIAL_LINK_TEXT, "部分链接") # 通过部分链接文字找
# 查找多个相同元素(返回列表)
elements = driver.find_elements(By.CSS_SELECTOR, ".item")3. 基本操作用法:对找到的元素进行各种操作# 点击元素(按钮、链接等)
element.click()
# 在输入框中输入文本
element.send_keys("要输入的文本")
# 清空输入框内容
element.clear()
# 获取元素显示的文本内容
text = element.text
print(text) # 打印获取的文本
# 获取元素的属性值(如value、href等)
value = element.get_attribute("value") # 获取输入框的值
href = element.get_attribute("href") # 获取链接地址
# 判断元素状态
is_displayed = element.is_displayed() # 元素是否可见
is_enabled = element.is_enabled() # 元素是否可用
is_selected = element.is_selected() # 元素是否被选中(复选框、单选框)4. 键盘操作用法:模拟键盘按键,实现快捷键操作# 组合键操作(常用于复制粘贴等)
element.send_keys(Keys.CONTROL, 'a') # Ctrl+A 全选文本
element.send_keys(Keys.CONTROL, 'c') # Ctrl+C 复制
element.send_keys(Keys.CONTROL, 'v') # Ctrl+V 粘贴
# 特殊按键
element.send_keys(Keys.ENTER) # 按回车键(提交表单)
element.send_keys(Keys.TAB) # 按Tab键(切换焦点)
element.send_keys(Keys.ESCAPE) # 按ESC键(取消操作)
element.send_keys(Keys.DELETE) # 按Delete键
element.send_keys(Keys.BACKSPACE) # 按退格键
element.send_keys(Keys.ARROW_UP) # 按方向键上
# 实用示例:清空输入框并输入新内容
input_box = driver.find_element(By.ID, "search")
input_box.send_keys(Keys.CONTROL, 'a') # 全选
input_box.send_keys(Keys.DELETE) # 删除
input_box.send_keys("新的搜索内容") # 输入新内容5. 鼠标操作用法:模拟鼠标的各种操作# 鼠标悬停(显示下拉菜单等)
ActionChains(driver).move_to_element(element).perform()
# 右键点击(显示右键菜单)
ActionChains(driver).context_click(element).perform()
# 双击元素
ActionChains(driver).double_click(element).perform()
# 拖拽元素从source到target位置
ActionChains(driver).drag_and_drop(source, target).perform()
# 拖拽元素到指定距离(x轴100像素,y轴0像素)
ActionChains(driver).click_and_hold(element).move_by_offset(100, 0).release().perform()
# 实用示例:滑动滑块
slider = driver.find_element(By.CSS_SELECTOR, ".slider")
ActionChains(driver).click_and_hold(slider).move_by_offset(50, 0).release().perform()6. 等待机制用法:等待页面元素加载完成,避免操作失败# 固定等待(简单但不推荐,会浪费时间)
sleep(2) # 等待2秒
# 显式等待(推荐使用,更智能)
wait = WebDriverWait(driver, 10) # 最多等待10秒
# 等待元素出现在DOM中
element = wait.until(EC.presence_of_element_located((By.ID, "myElement")))
# 等待元素可以被点击
element = wait.until(EC.element_to_be_clickable((By.ID, "myButton")))
# 等待元素可见
element = wait.until(EC.visibility_of_element_located((By.ID, "myDiv")))
# 等待元素消失(如加载动画)
wait.until(EC.invisibility_of_element_located((By.ID, "loading")))
# 实用示例:等待搜索结果加载
search_button = driver.find_element(By.ID, "search-btn")
search_button.click()
# 等待结果列表出现
results = wait.until(EC.presence_of_element_located((By.CLASS_NAME, "results")))7. 下拉框操作用法:操作HTML的select下拉框from selenium.webdriver.support.ui import Select
# 找到下拉框并创建Select对象
dropdown = driver.find_element(By.ID, "country")
select = Select(dropdown)
# 三种选择方式
select.select_by_visible_text("中国") # 通过显示文本选择
select.select_by_value("china") # 通过value属性选择
select.select_by_index(1) # 通过索引选择(从0开始)
# 获取选项信息
all_options = select.options # 获取所有选项
selected_option = select.first_selected_option # 获取当前选中项
print(selected_option.text) # 打印选中项文本
# 取消选择(多选下拉框)
select.deselect_by_visible_text("中国")
select.deselect_all() # 取消所有选择8. 窗口和标签页用法:处理多个浏览器窗口或标签页# 保存当前窗口句柄(用于后续切换回来)
main_window = driver.current_window_handle
# 获取所有窗口句柄
all_windows = driver.window_handles
print(f"共有{len(all_windows)}个窗口")
# 点击链接打开新窗口后,切换到新窗口
link = driver.find_element(By.LINK_TEXT, "打开新窗口")
link.click()
# 切换到最新打开的窗口
driver.switch_to.window(driver.window_handles[-1])
# 用JavaScript打开新标签页
driver.execute_script("window.open('https://www.baidu.com');")
# 关闭当前窗口并切换回主窗口
driver.close()
driver.switch_to.window(main_window)
# 处理iframe框架
driver.switch_to.frame("frame_name") # 切换到iframe
driver.switch_to.frame(0) # 通过索引切换
driver.switch_to.default_content() # 切回主页面
# 实用示例:处理弹出窗口
original_window = driver.current_window_handle
# 点击按钮打开新窗口
driver.find_element(By.ID, "open-window").click()
# 等待新窗口出现
wait.until(lambda d: len(d.window_handles) > 1)
# 切换到新窗口
for window in driver.window_handles:
if window != original_window:
driver.switch_to.window(window)
break9. JavaScript执行用法:执行JavaScript代码解决复杂操作# 滚动页面到底部(加载更多内容)
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
# 滚动到指定元素位置
element = driver.find_element(By.ID, "target")
driver.execute_script("arguments[0].scrollIntoView();", element)
# 强制点击被遮挡的元素
hidden_button = driver.find_element(By.ID, "hidden-btn")
driver.execute_script("arguments[0].click();", hidden_button)
# 直接设置输入框的值(绕过输入限制)
input_box = driver.find_element(By.ID, "readonly-input")
driver.execute_script("arguments[0].value = '强制设置的值';", input_box)
# 修改元素样式(如显示隐藏元素)
driver.execute_script("arguments[0].style.display = 'block';", element)
# 获取页面信息
page_height = driver.execute_script("return document.body.scrollHeight;")
print(f"页面高度:{page_height}像素")
# 实用示例:无限滚动加载
last_height = driver.execute_script("return document.body.scrollHeight")
while True:
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
sleep(2) # 等待加载
new_height = driver.execute_script("return document.body.scrollHeight")
if new_height == last_height:
break # 没有新内容了
last_height = new_height10. 文件操作用法:处理文件上传和截图# 文件上传(找到文件选择器并传入文件路径)
file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
file_path = r"C:\Users\用户名\Desktop\要上传的文件.jpg"
file_input.send_keys(file_path)
# 多文件上传
files = [r"C:\file1.jpg", r"C:\file2.jpg"]
file_input.send_keys("\n".join(files))
# 整个页面截图
driver.save_screenshot("页面截图.png")
# 单个元素截图
element = driver.find_element(By.ID, "target")
element.screenshot("元素截图.png")
# 带时间戳的截图(避免文件名重复)
from datetime import datetime
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
driver.save_screenshot(f"截图_{timestamp}.png")
# 实用示例:自动化测试截图
def take_screenshot_on_error():
try:
# 执行测试步骤
driver.find_element(By.ID, "submit").click()
except Exception as e:
# 出错时自动截图
driver.save_screenshot("错误截图.png")
print(f"操作失败:{e}")11. 弹窗处理用法:处理JavaScript弹出的对话框# 等待弹窗出现并处理
try:
# 触发弹窗的操作
driver.find_element(By.ID, "alert-btn").click()
# 切换到弹窗
alert = driver.switch_to.alert
# 获取弹窗文本
alert_text = alert.text
print(f"弹窗内容:{alert_text}")
# 确认弹窗(点击确定)
alert.accept()
# 或者取消弹窗(点击取消)
# alert.dismiss()
except:
print("没有弹窗出现")
# 处理输入型弹窗(prompt)
try:
driver.find_element(By.ID, "prompt-btn").click()
alert = driver.switch_to.alert
alert.send_keys("要输入的文本") # 在弹窗中输入文本
alert.accept() # 确认
except:
print("没有输入弹窗")
# 实用示例:批量确认删除操作
delete_buttons = driver.find_elements(By.CLASS_NAME, "delete-btn")
for btn in delete_buttons:
btn.click()
# 等待确认弹窗
alert = WebDriverWait(driver, 5).until(lambda d: d.switch_to.alert)
alert.accept() # 确认删除12. Cookie操作用法:管理浏览器Cookie,实现登录状态保持等# 添加Cookie(通常用于模拟登录状态)
driver.add_cookie({
"name": "session_id",
"value": "abc123456",
"domain": "example.com"
})
# 获取指定Cookie
session_cookie = driver.get_cookie("session_id")
if session_cookie:
print(f"会话ID:{session_cookie['value']}")
# 获取所有Cookie
all_cookies = driver.get_cookies()
for cookie in all_cookies:
print(f"{cookie['name']}: {cookie['value']}")
# 删除指定Cookie
driver.delete_cookie("session_id")
# 删除所有Cookie(退出登录)
driver.delete_all_cookies()
# 实用示例:保存和恢复登录状态
import json
# 登录后保存Cookie
def save_cookies():
with open("cookies.json", "w") as f:
json.dump(driver.get_cookies(), f)
# 下次访问时恢复Cookie
def load_cookies():
try:
with open("cookies.json", "r") as f:
cookies = json.load(f)
for cookie in cookies:
driver.add_cookie(cookie)
driver.refresh() # 刷新页面使Cookie生效
except FileNotFoundError:
print("没有保存的Cookie文件")13. 浏览器控制用法:控制浏览器的基本行为# 页面导航
driver.get("https://www.baidu.com") # 打开网页
driver.back() # 后退到上一页
driver.forward() # 前进到下一页
driver.refresh() # 刷新当前页面
# 窗口大小控制
driver.maximize_window() # 最大化窗口
driver.minimize_window() # 最小化窗口
driver.set_window_size(1920, 1080) # 设置窗口大小
driver.fullscreen_window() # 全屏模式
# 获取窗口大小和位置
size = driver.get_window_size()
print(f"窗口大小:{size['width']} x {size['height']}")
position = driver.get_window_position()
print(f"窗口位置:({position['x']}, {position['y']})")
# 获取页面信息
title = driver.title # 获取页面标题
url = driver.current_url # 获取当前URL
page_source = driver.page_source # 获取页面源码
print(f"页面标题:{title}")
print(f"当前网址:{url}")
# 实用示例:检查页面是否正确加载
def check_page_loaded(expected_title):
actual_title = driver.title
if expected_title in actual_title:
print("页面加载成功")
return True
else:
print(f"页面加载异常,期望标题包含:{expected_title},实际标题:{actual_title}")
return False
# 设置浏览器位置(多显示器环境)
driver.set_window_position(0, 0) # 移动到左上角14. 常用操作模式用法:封装常用的操作组合,提高代码复用性# 清空输入框并输入新内容(最常用)
def input_text(element, text):
element.click() # 点击激活输入框
element.send_keys(Keys.CONTROL, 'a') # 全选现有内容
element.send_keys(Keys.DELETE) # 删除内容
element.send_keys(text) # 输入新内容
# 使用示例
search_box = driver.find_element(By.ID, "search")
input_text(search_box, "Python教程")
# 等待并点击(避免元素未加载完成)
def wait_and_click(driver, selector, timeout=10):
element = WebDriverWait(driver, timeout).until(
EC.element_to_be_clickable((By.CSS_SELECTOR, selector))
)
element.click()
return element
# 使用示例
wait_and_click(driver, "#submit-btn")
# 滚动到元素并点击(处理页面很长的情况)
def scroll_and_click(driver, element):
driver.execute_script("arguments[0].scrollIntoView();", element)
sleep(0.5) # 等待滚动完成
element.click()
# 安全点击(多种点击方式的组合)
def safe_click(driver, element):
try:
element.click() # 尝试普通点击
except ElementClickInterceptedException:
# 如果被遮挡,用JS点击
driver.execute_script("arguments[0].click();", element)
# 批量操作示例
def batch_delete_items():
items = driver.find_elements(By.CLASS_NAME, "item")
for item in items:
delete_btn = item.find_element(By.CLASS_NAME, "delete")
safe_click(driver, delete_btn)
sleep(1) # 等待删除完成15. 异常处理用法:处理自动化过程中的各种异常情况from selenium.common.exceptions import *
# 基本异常处理
try:
element = driver.find_element(By.ID, "submit")
element.click()
except NoSuchElementException:
print("找不到提交按钮,可能页面结构发生变化")
except TimeoutException:
print("页面加载超时,网络可能有问题")
except ElementClickInterceptedException:
print("按钮被其他元素遮挡,尝试滚动页面")
except StaleElementReferenceException:
print("元素引用已失效,需要重新查找元素")
# 完整的异常处理示例
def robust_click(driver, selector, max_retries=3):
"""健壮的点击函数,包含重试机制"""
for attempt in range(max_retries):
try:
element = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.CSS_SELECTOR, selector))
)
element.click()
return True # 成功点击
except TimeoutException:
print(f"第{attempt+1}次尝试:等待元素超时")
except ElementClickInterceptedException:
print(f"第{attempt+1}次尝试:元素被遮挡,尝试滚动")
driver.execute_script("window.scrollBy(0, 200);")
except Exception as e:
print(f"第{attempt+1}次尝试:未知错误 {e}")
if attempt < max_retries - 1:
sleep(2) # 重试前等待
print("所有尝试都失败了")
return False
# 使用示例
if robust_click(driver, "#difficult-button"):
print("成功点击按钮")
else:
print("点击失败,需要人工检查")16. 性能优化用法:提高自动化脚本的运行速度和稳定性# Chrome浏览器性能优化配置
chrome_options = webdriver.ChromeOptions()
# 禁用图片加载(大幅提升速度)
chrome_options.add_argument('--blink-settings=imagesEnabled=false')
# 无头模式(不显示浏览器界面,速度更快)
chrome_options.add_argument('--headless')
# 禁用GPU加速(避免某些环境下的问题)
chrome_options.add_argument('--disable-gpu')
# 禁用开发者工具
chrome_options.add_argument('--disable-dev-shm-usage')
# 设置页面加载策略(不等待所有资源加载完成)
chrome_options.add_argument('--page-load-strategy=eager')
# 禁用扩展
chrome_options.add_argument('--disable-extensions')
# 禁用通知
chrome_options.add_argument('--disable-notifications')
# 创建优化后的驱动
driver = webdriver.Chrome(options=chrome_options)
# 设置较短的页面加载超时
driver.set_page_load_timeout(30) # 30秒超时
# 实用示例:批量处理时的优化
def optimized_batch_process():
# 使用无头模式进行批量处理
options = webdriver.ChromeOptions()
options.add_argument('--headless')
options.add_argument('--disable-images')
driver = webdriver.Chrome(options=options)
urls = ["http://example1.com", "http://example2.com"]
results = []
for url in urls:
driver.get(url)
# 快速获取需要的信息
title = driver.title
results.append(title)
driver.quit()
return results17. 调试技巧用法:帮助定位和解决自动化脚本中的问题# 高亮显示元素(方便调试时查看)
def highlight_element(driver, element, color="red", width=3):
"""高亮显示元素"""
original_style = element.get_attribute("style")
driver.execute_script(
f"arguments[0].style.border='{width}px solid {color}';",
element
)
sleep(2) # 显示2秒
# 恢复原始样式
driver.execute_script(f"arguments[0].style='{original_style}';", element)
# 获取元素详细信息
def get_element_info(element):
"""获取元素的详细信息用于调试"""
info = {
"tag_name": element.tag_name,
"text": element.text,
"location": element.location,
"size": element.size,
"is_displayed": element.is_displayed(),
"is_enabled": element.is_enabled()
}
return info
# 使用示例
button = driver.find_element(By.ID, "submit")
print("按钮信息:", get_element_info(button))
highlight_element(driver, button) # 高亮显示按钮
# 检查元素是否在视口内
def is_element_in_viewport(driver, element):
"""检查元素是否在当前视口内"""
return driver.execute_script("""
var rect = arguments[0].getBoundingClientRect();
return (
rect.top >= 0 &&
rect.left >= 0 &&
rect.bottom <= window.innerHeight &&
rect.right <= window.innerWidth
);
""", element)
# 调试模式运行(添加详细日志)
def debug_click(driver, selector):
"""调试版本的点击函数"""
print(f"正在查找元素:{selector}")
try:
element = driver.find_element(By.CSS_SELECTOR, selector)
print(f"找到元素:{element.tag_name}")
if not element.is_displayed():
print("警告:元素不可见")
if not element.is_enabled():
print("警告:元素不可用")
if not is_element_in_viewport(driver, element):
print("元素不在视口内,滚动到元素位置")
driver.execute_script("arguments[0].scrollIntoView();", element)
highlight_element(driver, element) # 高亮显示
element.click()
print("成功点击元素")
except Exception as e:
print(f"点击失败:{e}")
driver.save_screenshot("debug_error.png") # 出错时截图18. 移动端测试用法:模拟移动设备进行测试# 模拟不同移动设备
mobile_devices = {
"iPhone X": {"deviceName": "iPhone X"},
"iPad": {"deviceName": "iPad"},
"Galaxy S5": {"deviceName": "Galaxy S5"},
"自定义": {
"deviceMetrics": {
"width": 375,
"height": 667,
"pixelRatio": 2.0
},
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 13_0 like Mac OS X)"
}
}
# 创建移动端浏览器
def create_mobile_driver(device="iPhone X"):
chrome_options = webdriver.ChromeOptions()
chrome_options.add_experimental_option(
"mobileEmulation",
mobile_devices[device]
)
return webdriver.Chrome(options=chrome_options)
# 使用示例
mobile_driver = create_mobile_driver("iPhone X")
mobile_driver.get("https://m.baidu.com")
# 触摸操作(注意:TouchActions在新版本中已弃用)
# 推荐使用ActionChains进行移动端操作
def mobile_swipe(driver, start_x, start_y, end_x, end_y):
"""模拟手机滑动操作"""
ActionChains(driver)\
.move_by_offset(start_x, start_y)\
.click_and_hold()\
.move_by_offset(end_x - start_x, end_y - start_y)\
.release()\
.perform()
# 移动端特有操作示例
def mobile_test_example():
driver = create_mobile_driver("iPhone X")
driver.get("https://m.taobao.com")
# 模拟向下滑动加载更多
for i in range(3):
driver.execute_script("window.scrollBy(0, 500);")
sleep(2)
# 检查移动端特有元素
try:
menu_btn = driver.find_element(By.CLASS_NAME, "mobile-menu")
menu_btn.click()
print("成功打开移动端菜单")
except:
print("未找到移动端菜单")
driver.quit()
# 响应式测试(测试不同屏幕尺寸)
def responsive_test():
driver = webdriver.Chrome()
# 测试不同分辨率
resolutions = [
(1920, 1080), # 桌面
(1366, 768), # 笔记本
(768, 1024), # 平板
(375, 667) # 手机
]
for width, height in resolutions:
driver.set_window_size(width, height)
driver.get("https://example.com")
# 检查布局是否正常
title = driver.title
print(f"分辨率 {width}x{height}: {title}")
# 截图保存
driver.save_screenshot(f"responsive_{width}x{height}.png")
sleep(2)
driver.quit()19. 参数化测试用法:使用不同的测试数据多次运行同一个测试,提高测试覆盖率import pytest
# 基本参数化测试
@pytest.mark.parametrize("username,password", [
("user1", "pass1"),
("user2", "pass2"),
("admin", "admin123")
])
def test_login(driver, username, password):
"""测试不同用户的登录功能"""
driver.get("https://example.com/login")
# 输入用户名
username_input = driver.find_element(By.ID, "username")
username_input.send_keys(username)
# 输入密码
password_input = driver.find_element(By.ID, "password")
password_input.send_keys(password)
# 点击登录
login_btn = driver.find_element(By.ID, "login-btn")
login_btn.click()
# 验证登录结果
assert "欢迎" in driver.page_source
# 多参数参数化测试
@pytest.mark.parametrize("start_city,end_city,date,expected_result", [
("北京", "上海", "2024-12-01", "航班信息"),
("广州", "深圳", "2024-12-02", "航班信息"),
("成都", "重庆", "2024-12-03", "航班信息")
])
def test_flight_search(driver, start_city, end_city, date, expected_result):
"""测试航班搜索功能"""
driver.get("https://flights.example.com")
# 输入出发城市
start_input = driver.find_element(By.ID, "departure")
start_input.clear()
start_input.send_keys(start_city)
# 输入到达城市
end_input = driver.find_element(By.ID, "arrival")
end_input.clear()
end_input.send_keys(end_city)
# 选择日期
date_input = driver.find_element(By.ID, "date")
date_input.clear()
date_input.send_keys(date)
# 搜索
search_btn = driver.find_element(By.ID, "search")
search_btn.click()
# 等待结果
WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.CLASS_NAME, "flight-results"))
)
# 验证结果
assert expected_result in driver.page_source
# 使用字典进行参数化(更清晰的数据结构)
test_data = [
{
"name": "测试用例1",
"url": "https://example1.com",
"title": "Example 1",
"screenshot": "test1.png"
},
{
"name": "测试用例2",
"url": "https://example2.com",
"title": "Example 2",
"screenshot": "test2.png"
}
]
@pytest.mark.parametrize("test_case", test_data)
def test_website_title(driver, test_case):
"""测试网站标题"""
driver.get(test_case["url"])
# 等待页面加载
WebDriverWait(driver, 10).until(
EC.title_contains(test_case["title"])
)
# 截图
driver.save_screenshot(test_case["screenshot"])
# 验证标题
assert test_case["title"] in driver.title
# 从外部文件读取测试数据
import json
def load_test_data(file_path):
"""从JSON文件加载测试数据"""
with open(file_path, 'r', encoding='utf-8') as f:
return json.load(f)
# 创建测试数据文件 test_data.json
"""
[
{"city": "北京", "keyword": "美食", "expected": "餐厅"},
{"city": "上海", "keyword": "景点", "expected": "旅游"},
{"city": "广州", "keyword": "购物", "expected": "商场"}
]
"""
@pytest.mark.parametrize("data", load_test_data("test_data.json"))
def test_search_with_external_data(driver, data):
"""使用外部数据进行搜索测试"""
driver.get("https://map.baidu.com")
# 搜索
search_box = driver.find_element(By.ID, "sole-input")
search_box.clear()
search_box.send_keys(f"{data['city']} {data['keyword']}")
search_btn = driver.find_element(By.ID, "search-button")
search_btn.click()
# 等待结果
sleep(3)
# 验证结果包含期望内容
assert data['expected'] in driver.page_source
# 条件参数化(根据条件跳过某些测试)
@pytest.mark.parametrize("browser,url", [
("chrome", "https://example.com"),
("firefox", "https://example.com"),
pytest.param("safari", "https://example.com",
marks=pytest.mark.skipif(True, reason="Safari not available"))
])
def test_cross_browser(browser, url):
"""跨浏览器测试"""
if browser == "chrome":
driver = webdriver.Chrome()
elif browser == "firefox":
driver = webdriver.Firefox()
driver.get(url)
assert "Example" in driver.title
driver.quit()
# 参数化测试类
class TestUserManagement:
@pytest.mark.parametrize("user_type,expected_menu", [
("admin", "用户管理"),
("user", "个人中心"),
("guest", "登录")
])
def test_user_menu(self, driver, user_type, expected_menu):
"""测试不同用户类型的菜单"""
# 模拟不同用户登录
self.login_as_user(driver, user_type)
# 检查菜单
menu = driver.find_element(By.CLASS_NAME, "user-menu")
assert expected_menu in menu.text
def login_as_user(self, driver, user_type):
"""辅助方法:模拟不同类型用户登录"""
users = {
"admin": ("admin", "admin123"),
"user": ("testuser", "test123"),
"guest": (None, None)
}
if users[user_type][0]: # 如果不是guest
driver.get("https://example.com/login")
username, password = users[user_type]
driver.find_element(By.ID, "username").send_keys(username)
driver.find_element(By.ID, "password").send_keys(password)
driver.find_element(By.ID, "login-btn").click()
else:
driver.get("https://example.com") # guest直接访问首页
# 实用示例:电商网站商品搜索测试
@pytest.mark.parametrize("keyword,min_results,screenshot_name", [
("手机", 10, "phone_search.png"),
("笔记本电脑", 5, "laptop_search.png"),
("耳机", 8, "headphone_search.png"),
("", 0, "empty_search.png") # 测试空搜索
])
def test_product_search(driver, keyword, min_results, screenshot_name):
"""测试商品搜索功能"""
driver.get("https://shop.example.com")
# 搜索商品
search_box = driver.find_element(By.ID, "search-input")
search_box.clear()
if keyword: # 如果关键词不为空
search_box.send_keys(keyword)
search_btn = driver.find_element(By.ID, "search-btn")
search_btn.click()
# 等待搜索结果
WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.CLASS_NAME, "product-list"))
)
# 截图
driver.save_screenshot(screenshot_name)
# 验证结果数量
products = driver.find_elements(By.CLASS_NAME, "product-item")
if keyword: # 有关键词时应该有结果
assert len(products) >= min_results, f"搜索'{keyword}'的结果少于{min_results}个"
else: # 空搜索可能没有结果或显示默认商品
print(f"空搜索返回{len(products)}个结果")
-
五分钟开发ToDoListAPP后端
https://www.iarc.top/499.html
2025-08-14T21:15:00+08:00
使用CodeBuddy IDE五分钟内即可完成ToDoList基础后端开发,在这个AI工具发达的时代,我们已不需要将全部的知识装进大脑,只需有一个大的框架,细节交给AI即可快速建立项目。环境配置:Node.js将项目需求描述给codebuddy,我这里模型选的是GPT-5-nano,只需稍等几十秒钟,项目将会完全构建以下是codebuddy生成的项目(未进行任何修改)index.js:const express = require('express');
const app = express();
const port = process.env.PORT || 3000;
// In-memory storage
let todos = [];
let nextId = 1;
function findTodo(id) {
return todos.find(t => t.id === id);
}
app.use(express.json());
// Get all todos, with optional filtering by completion status
app.get('/todos', (req, res) => {
const completed = req.query.completed;
if (completed !== undefined) {
const isDone = completed === 'true';
return res.json(todos.filter(t => t.completed === isDone));
}
res.json(todos);
});
// Get a single todo by id
app.get('/todos/:id', (req, res) => {
const id = parseInt(req.params.id, 10);
const t = todos.find(t => t.id === id);
if (!t) return res.status(404).json({ error: 'Todo not found' });
res.json(t);
});
// Create a new todo
app.post('/todos', (req, res) => {
const { title, description } = req.body;
if (!title) return res.status(400).json({ error: 'title is required' });
const todo = {
id: nextId++,
title,
description: description || '',
completed: false,
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString()
};
todos.push(todo);
res.status(201).json(todo);
});
// Update an existing todo
app.put('/todos/:id', (req, res) => {
const id = parseInt(req.params.id, 10);
const t = todos.find(t => t.id === id);
if (!t) return res.status(404).json({ error: 'Todo not found' });
const { title, description, completed } = req.body;
if (title !== undefined) t.title = title;
if (description !== undefined) t.description = description;
if (completed !== undefined) t.completed = completed;
t.updatedAt = new Date().toISOString();
res.json(t);
});
// Delete a todo
app.delete('/todos/:id', (req, res) => {
const id = parseInt(req.params.id, 10);
const idx = todos.findIndex(t => t.id === id);
if (idx === -1) return res.status(404).json({ error: 'Todo not found' });
const removed = todos.splice(idx, 1);
res.json(removed[0]);
});
// Health check (optional)
app.get('/health', (req, res) => {
res.json({ status: 'ok', todoCount: todos.length });
});
app.listen(port, () => {
console.log(`Todo backend listening at http://localhost:${port}`);
});
package.json{
"name": "todolist-backend",
"version": "1.0.0",
"description": "In-memory Todo List backend using Node.js + Express",
"main": "index.js",
"scripts": {
"start": "node index.js"
},
"dependencies": {
"express": "^4.18.2"
}
}接下来进行npm安装项目运行所需的库,安装完后直接开始运行看看能不能正常跑起来测试阶段:测试接口:(内存存储,重启丢失数据)请求方式路径功能GET/todos获取所有待办,可通过查询参数 completed=true/false 进行筛选POST/todos创建待办,body 示例 { "title": "示例", "description": "可选" }GET/todos/:id获取指定待办PUT/todos/:id更新待办,支持 title、description、completedDELETE/todos/:id删除待办GET/health健康检查获取所有待办:目前初始化成功但还没有添加数据创建待办由于我没有进行前端的编写,这里直接在浏览器控制台模拟前端js发送请求完成接下来的测试,js代码如下:fetch("/todos", {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ "title": "待办名字", "description": "待办描述" })
})已成功创建两个待办事项,重新get请求todos可查看已成功添加通过id获取指定待办信息更新已有待办事项内容成功更新删除待办事项健康检测注意事项: 该版本的待办事项数据仅保存在内存,重启后将全部丢失,仅适合开发/测试阶段。不过接下来可以让codebuddy优化成使用json文件存储或者使用数据库(SQLite、PostgreSQL、MongoDB 等)存储数据,交给各位去继续探索了。评论区留言“CodeBuddy”抽5位送永久体验码!CodeBuddyIDE官网:https://www.codebuddy.ai/我的博客即将同步至腾讯云开发者社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=6g36nynyzup
-
Joe文章列表添加渐变颜色效果
https://www.iarc.top/452.html
2024-07-07T00:41:00+08:00
一个大气的文章列表CSS渐变动画,也可以使用图片作为渐变背景,,效果如下(鼠标移动到元素上后颜色会更加突出):日间模式夜间模式接下来需要编辑的文件以及相对Joe主题的文件路径:joe.index.js /Joe/assets/jsjoe.index.css /Joe/assets/cssjoe.mode.css/Joe/assets/css开始(共三部分){tabs}{tabs-pane label="添加HTML代码"}打开joe.index.js文件找到如图所示位置可以直接搜joe_list__item wow default定位到,其实一打开就是了。在第一个a标签元素后面加入如下代码<div class="article-banner-wrap"></div>
<div class="article-banner"></div>{/tabs-pane}{tabs-pane label="添加CSS代码"}直接将下面的css代码复制粘贴到joe.index.css文件的最后面就行了/*首页列表渐变*/
.article-banner-wrap {
position: absolute;
height: 100%;
width: 50%;
right: 0;
top: 0;
}
.article-banner {
visibility: hidden;
opacity: .2;
position: absolute;
height: 100%;
width: 50%;
right: 0;
top: 0;
z-index: 0;
background-repeat: no-repeat;
background-size: cover;
-webkit-background-size: cover;
-o-background-size: cover;
background-position: center center;
transition: opacity 0.2s;
-webkit-mask-image: -webkit-linear-gradient(right, rgba(0, 0, 0, 1) 0%, rgba(0, 0, 0, 0) 100%);
border-radius: 8px;
background:linear-gradient(to left,#2BC0E4,#EAECC6);
visibility: visible;
animation: banner-show 1s;
}
.joe_list__item.default:hover .article-banner{opacity: 1;}其中的background可以改成图片地址,这样效果就是图片了,但图片会拖累网站加载速度,可自行决定是否要换成图片。{/tabs-pane}{tabs-pane label="适配夜间模式"}打开joe.mode.css文件,将以下CSS代码加入文件底部即可。/*首页列表图片渐变夜间模式*/
html[data-night='night'] .article-banner{
background: linear-gradient(to left,#1F1C2C,#928DAB);
opacity:0.1
}我这里不是最底部是因为我后来又加其他东西了,其实也不是一定要最底部,只是方便小白操作和自己描述了。{/tabs-pane}{/tabs}
-
腾讯企业邮箱接受邮件后在普通微信内提醒的方法
https://www.iarc.top/432.html
2024-05-02T00:32:00+08:00
前言企业邮箱注册教程在网上一搜就有很多视频教程,免费版的有阿里、网易、腾讯企业邮箱,在这就不说咋注册了(去掉域名解析生效时间,连一分钟都用不了)。吐槽一下我当时腾讯企业邮箱公众号也关注了,新邮件消息提醒也打开了,腾讯企业邮箱小程序里的消息提醒也打开了,但实际一测试在微信里还是没有任何的提醒,只有企业微信里提醒了。后来我按住它那个网页端研究了半天,页面内的有关的没关的按钮全点了一遍,应用什么的乱七八糟的也创建了一遍都没能实现腾讯企业邮箱接收邮件后在微信内提醒这个功能,在网上也搜了一圈发现都是说的乱七八糟的而且没有一点用,后来还是找了个客服终于解决了,然后发现其实实现这个功能也是30秒之内就能结束战斗的,结果我花了30多分钟 ::(心碎)登录企业微信网页端找到“我的企业”==>“微信插件”==>“邀请关注”用在该企业内的微信扫码关注一下,不在的就加入一下即可大功告成,在右上角加好的设置里将接受企业消息打开就行了最终效果在企业邮箱收到邮件的第一时间微信能就能收到消息提醒,就和QQ邮箱那个几乎一样,这样就能把企业微信给卸载了直留个微信就能使用企业邮箱收发邮件了。 :$(强)
-
给博客评论框添加一个简单的滑动背景图
https://www.iarc.top/417.html
2024-03-18T18:06:00+08:00
纯css实现,代码各个主题都是通用的,这里以Joe主题为例效果:css代码:.joe_comment__respond-form .body{padding:15px;background:url(https://www.iarc.top/usr/uploads/2024/03/1257364055.png);background-position:right;background-repeat:no-repeat;resize:none;}.joe_comment__respond-form .body:hover{background-position-x:4000px;transition:ease-in-out 2s;}.joe_comment__respond-form .body 就是评论框主题,可以直接在前端按F12查看自己主题的是哪个组图片:最好自己保存下来,以防失效。
-
百度资源搜索平台提示"该站点为低质站点,暂不可添加,请持续优化后,再行尝试。"的解决办法
https://www.iarc.top/414.html
2024-03-17T16:20:00+08:00
前一段时间,我忽然发现博客的文章百度推送一直失败,然后我就登陆了一下百度搜索资源平台,发现自己之前添加并验证好的站点竟然被清了,然后我就试着重新添加回来,结果添加站点时直接提示:该站点为低质站点,暂不可添加,请持续优化后,再行尝试。然后我第一时间就去找百度资源平台客服反馈,结果一直都是个人工智障还没法转人工,一直答非所问,而且提供的反馈链接都失效了还发给我。所以先给各位排除掉这个想法。了解百度的低质量站点标准内容质量:内容是否原创,是否有价值,是否与主题相关。用户体验:网站的导航是否清晰,页面加载速度是否快,是否有过多的广告干扰用户浏览。技术优化:网站的结构是否合理,URL是否简洁,是否有移动设备适配等。解决办法我不能保证这是最短路径,但是我就是这样边投诉边反馈的溜了一大圈后确实是恢复了提供高质量内容原创性创作原创内容:确保网站发布的内容是原创的,避免抄袭或重复内容,删除全部搬运内容。定期更新:保持内容的新鲜度,定期发布新文章或更新现有内容。价值性提供实用信息:内容应具有实用性,解决用户的问题或满足其需求。深度分析:不仅仅提供表面信息,还要深入分析,提供行业洞察。优化用户体验网站设计清晰的导航:设计直观的菜单和导航结构,帮助用户快速找到所需信息。页面加载速度:优化图片大小、减少不必要的插件和脚本,提高页面加载速度。广告策略适度的广告:确保广告不会过分干扰用户浏览,避免使用弹出式广告。内容与广告的平衡:广告应与内容相关,不应影响用户阅读体验。技术SEO优化网站结构逻辑清晰的URL结构:使用易于理解的URL,避免过长和复杂的URL结构。内部链接:合理设置内部链接,帮助百度爬虫更好地理解网站结构。移动优化响应式设计:确保网站在各种设备上都能良好显示。加速移动页面:使用AMP等技术提升移动页面加载速度。建立权威链接获取高质量外链:通过内容营销、合作伙伴关系等方式获取高质量的外部链接。避免不良链接:定期检查并移除指向低质量或不相关网站的链接,尤其是死链接不能有。检查域名解析问题到域名控制面板把那些无法正常打开的域名解析全部删了或者暂停解析,因为百度资源搜索平台的算法好像是只要有一个子域名被列为低质站点,其主域名也会被连带列入。百度网址安全中心去百度网址安全中心-误报申诉进行申诉。然后反馈的邮件会说没问题百度资源平台的清退通知去看关于搜索资源平台清退风险资源验证关系的通知然后通过资源平台验证关系清退反馈进行反馈等待恢复我从发现自己网站被列为低质站点到解决恢复大概时间是不到4个月,期间网站也不用关闭,但是网站加载速度最好控制到10s之内加载完成,然后文章该咋更咋更,也不用那么频繁,只要是原创的就行,我当时好像是一个月就更一两篇甚至一篇也不更,恢复期间收录量确实会下降,但三四个月他也掉不完。
-
文字生成视频:StableVideo每天免费使用15次
https://www.iarc.top/406.html
2024-02-24T16:45:28+08:00
在这个短视频的时代,文字创作者们,是时候给你们的文字穿上华丽的视频外衣了!Sora目前好像没有开发使用,所以我找了一个免费(每天能免费用15次)且类似的先尝尝鲜,但是效果貌似还达不到Sora宣传的那样 ::(呵呵)使用方法1.打开stablevideo登陆,两个选项,一个是文生视频,一个是图生成视频,我这里以文生成视频为例:2.输入描述词(必须是英文)3.选择好要继续生成的视频的封面并选择运镜等配置4.开始生成视频(说白了还是图生视频)然后等个几分钟5.生成完成直接下载即可{message type="warning" content="生成的视频很短,达不到Sora的一分钟,只有5秒左右。"/}
-
解决蓝奏云分享链接无法访问的实用方案
https://www.iarc.top/400.html
2024-02-21T02:38:00+08:00
注意哈,是无法访问,不是分享被取消了之类的。当蓝奏云链接失效时,如何快速恢复访问?可能原因蓝奏云服务暂时不可用:服务提供商可能会进行维护或遇到技术问题,导致暂时无法访问。域名DNS问题:域名系统(DNS)故障可能导致链接无法解析,从而无法访问文件。网络连接不稳定:您的网络连接问题也可能导致无法加载蓝奏云链接。解决方法:更换主域名在遇到无法访问的情况时,尝试更换蓝奏云的主域名是一个简单而有效的解决方案。蓝奏云有多个主域名,包括但不限于lanzv.com、lanzoub.com、lanzouu.com、lanzouc.com、lanzoue.com和lanzoui.com。根据用户反馈,lanzoui.com域名的访问率较高,可能是因为使用人数较少。操作示例:假设您尝试访问以下链接:https://xql.lanzv.com/izGMs1otfqpg,如果无法打开,您可以尝试更换为:https://xql.lanzoui.com/izGMs1otfqpg。这样的尝试往往能够解决问题。总结:通过更换蓝奏云的主域名,您可以在大多数情况下恢复对分享链接的访问。这种方法对于解决由于网络不稳定或主域名故障导致的访问问题特别有效。希望这些信息能够帮助那些遇到类似问题的用户。
-
真正能稳定赚钱的挂机项目:网心云(电脑手机都可以)
https://www.iarc.top/362.html
2023-12-18T04:11:00+08:00
先声明一下不是广告哈,亲测真的能捞到钱,随便找个不频繁使用的手机连上家里WIFI就能赚钱了。 ::(真棒)下面我只介绍一种最简单、最基础的玩法(一天大概赚1元左右) :@(欢呼) ,当然高级玩法能赚更多但相较麻烦,感兴趣的可以去网上搜一下教程就行了第一步,下载手机宝官网下载地址:点我前往下载手机宝APP后,直接一键启动,连接WI-FI,就能直接开始赚零花钱,在手机宝APP“我的”界面会有设备SN码,这个设备SN码要在网心云APP上绑定一下,这样这台安装手机宝的设备的收益都会直接进到你的网心云APP的账户上了。邀请码:kDMQh9uh(好像只有新用户才能领到钱) ::(玫瑰)第二步,下载网心云APP并绑定挂机设备官网下载地址:点我前往网心云APP使用来绑定那个使用手机宝APP赚钱的设备的,也就是说网心云APP只是用来查看你邦迪设备收益的,注意余额,每周二才能提现!(只要余额大于1元就能全部提现了)如果你还没注册的话,千万别着急注册!通过下面活动二维码注册,然后再在手机宝登陆输上面的邀请码,我保证通过这二维码注册绝对不会降低您日后的收益的,而且我们双方都可以拿到一定时长的加成卡和小钱钱。 ::(滑稽) ::(玫瑰) 最近这半个月的收益没有一直挂着,有好几天忘挂后台了,有的是上学走之前忘给手机充电了,估计挂了半天没电关机了,完整给后台挂了一整天的次数应该就5次,有时候有活动比如加成卡之类的,一天1块多,我家里网速也不是很快,可以看一下这个测速,我感觉应该没人比我更慢了吧 ::(笑尿) 预估自己一个月能赚多少钱:点我前往断断续续挂了半个月的真实余额:因为我星期二10点到18点都在学校上课,所以就没来得及提现,不过先攒着,凑机会再提现。 ::(狗头)后续
-
2023年如何获取中国移动光猫的超级密码?
https://www.iarc.top/356.html
2023-12-17T00:49:41+08:00
第一步 获取MAC打开命令提示符(Windows)或终端(macOS)。输入以下命令并按回车:arp -a在弹出的对话框中,找到与192.168.1.1对应的一行。例如:192.168.1.1 b0:30:55:83:59:18将MAC地址(b0:30:55:83:59:18)记录下来。注意,在MAC地址中,如果有两个冒号之间只有一个字符。需要在这个字符前面补零以凑成两位。 如::a:变成:0a:将所有字母转换为大写,并删除冒号,得到:B0:30:55:83:59:18请注意,这只是一种获取特定设备的MAC地址的方法,并且仅适用于您自己的网络。任何非法使用或未经授权访问他人设备的行为都是违法的。请谨慎操作,并遵守相关法律法规。第二步 开启Telnet在浏览器中输入以下网址:http:/192.168.1.1/cgi-bin/telnetenable.cgi?telnetenable=1&key=B03055835918按回车打开该网址。如果一切正常,您将在浏览器中看到 "telnet开启" 的提示。请注意,此方法可能仅适用于部分的路由器,并且可能不适用于所有路由器。第三步 获取超级密码打开命令提示符(Windows)或终端(macOS)。输入以下命令并按回车:telnet 192.168.1.1如果一切正常,您将在命令行中看到 "login:" 的提示。在 "login:" 后面输入以下内容并按回车:admin然后会提示您输入密码。在 "Password:" 后面输入以下内容并按回车:Fh@835918此处的 "835918" 是MAC地址的后6位。如果一切正常,您将在命令行中看到一个 "#" 符号。输入以下命令并按回车:load_cli factory
show admin_name
show admin_pwd此时,命令行将显示管理员账户名和密码。使用获取到的管理员账户名和密码,访问网址 http://192.168.1.1 即可进入管理员模式。