
用法:导入必要的模块,初始化浏览器驱动
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")用法:在网页中找到你要操作的元素(按钮、输入框等)
# 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")用法:对找到的元素进行各种操作
# 点击元素(按钮、链接等)
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() # 元素是否被选中(复选框、单选框)用法:模拟键盘按键,实现快捷键操作
# 组合键操作(常用于复制粘贴等)
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("新的搜索内容") # 输入新内容用法:模拟鼠标的各种操作
# 鼠标悬停(显示下拉菜单等)
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()用法:等待页面元素加载完成,避免操作失败
# 固定等待(简单但不推荐,会浪费时间)
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")))用法:操作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() # 取消所有选择用法:处理多个浏览器窗口或标签页
# 保存当前窗口句柄(用于后续切换回来)
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)
break用法:执行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_height用法:处理文件上传和截图
# 文件上传(找到文件选择器并传入文件路径)
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}")用法:处理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() # 确认删除用法:管理浏览器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文件")用法:控制浏览器的基本行为
# 页面导航
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) # 移动到左上角用法:封装常用的操作组合,提高代码复用性
# 清空输入框并输入新内容(最常用)
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) # 等待删除完成用法:处理自动化过程中的各种异常情况
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("点击失败,需要人工检查")用法:提高自动化脚本的运行速度和稳定性
# 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 results用法:帮助定位和解决自动化脚本中的问题
# 高亮显示元素(方便调试时查看)
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") # 出错时截图用法:模拟移动设备进行测试
# 模拟不同移动设备
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()
]]>将项目需求描述给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、completed |
| DELETE | /todos/:id | 删除待办 |
| GET | /health | 健康检查 |

目前初始化成功但还没有添加数据
由于我没有进行前端的编写,这里直接在浏览器控制台模拟前端js发送请求完成接下来的测试,js代码如下:
fetch("/todos", {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ "title": "待办名字", "description": "待办描述" })
})
已成功创建两个待办事项,重新get请求todos可查看已成功添加



成功更新



注意事项:
该版本的待办事项数据仅保存在内存,重启后将全部丢失,仅适合开发/测试阶段。不过接下来可以让codebuddy优化成使用json文件存储或者使用数据库(SQLite、PostgreSQL、MongoDB 等)存储数据,交给各位去继续探索了。
评论区留言“CodeBuddy”抽5位送永久体验码!
CodeBuddyIDE官网:https://www.codebuddy.ai/
我的博客即将同步至腾讯云开发者社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=6g36nynyzup

ClawCloud Run,它是阿里云青春版Claw Cloud家的,有点像Vercel那种在线开发平台。不管是啥应用、程序,包括Docker应用,都能快速部署,现在已经支持76款热门开源应用一键搞定了。

福利这块:如果你的GitHub账号注册满180天,能终身享受每月5美金的免费额度;新用户刚注册,也会直接送5美金体验额度,但用完就没了。

资源配置呢,免费套餐最高能给到10GB流量、4核vCPU、8GB内存、10GB磁盘空间,还有1个工作区,很适合用来部署轻量级的小应用。举个例子,部署Alist搭个个人网盘管理系统,一天下来也就0.07刀,每月5刀的免费额度完全够用,轻量场景用着特别合适。
注册也简单,直接用GitHub账号登录就行。可选地区有美国东部、德国、美国西部、新加坡和日本。从国内访问速度看,新加坡和日本这两个节点更推荐。

注册完之后,界面上会显示几个核心功能模块:App Launchpad(应用启动)、Database(数据库)、Devbox(开发沙盒)、Object Storage(对象存储)、App Store(应用商店)和Terminal(终端)。
注册地址在这:https://console.run.claw.cloud/signin?link=BSYQATGONVWT]]>

活动链接:http://idc.arcpi.cn

公益二级域名:http://212025.xyz
制作地址:http://web.iarc.top

最高可支持8K无水印视频下载
该工具为英文,如果有的看不懂需要用翻译软件,然后下载速度取决于你的梯的速度,支持下载视频合集。
{cloud title="油管无水印视频下载" type="default" url="https://pan.quark.cn/s/9f01f8c5ee7b" password=""/}
]]>
魔幻粒子新年祝福是一段基于HTML5 Canvas制作的粒子爆炸,矩阵显字的动画特效代码,给人一种非常大气的视觉感,欢迎对此段代码感兴趣的朋友前来下载使用。
源码由HTML+CSS+JS组成,记事本打开源码文件可以进行内容文字之类的修改
{cloud title="魔幻粒子新年祝福源码" type="default" url="https://pan.quark.cn/s/3323cd0b8b51" password=""/}
]]>| 1年 | 配置 |
|---|---|
| 99元 | 2核2G,3M固定带宽不限流量,40G ESSD Entry云盘 |
{abtn icon="fa-diamond" color="#ff6800" href="https://www.aliyun.com/benefit?scm=20140722.M_185600978.P_114.MO_2274-ID_10517682-MID_10517682-CID_31491-ST_11142-V_1&source=5176.29345612&userCode=m2urtzth" radius="5px" content="点我前往阿里云活动页"/}

{progress percentage="90%" color="#fff56b"/}
宽带只有3M,装个win10系统当成云电脑从网上下文件网速几十M比3M快多了,但是从服务器上下文件到本地就3M左右,个人博客类的站点够用。
{progress percentage="99%" color="#fff56b"/}
排除被人为打黑洞里了一次,用了一年期间没有连不上的情况。
| 1年 | 配置 |
|---|---|
| 99元 | 2核2G,100Mbps优质BGP宽带每月限600GB流量(超出限速1M),30GB SSD存储 |

香港AMD Linux VPS折后价格表:
| 1年 | 配置 |
|---|---|
| 81.4元 | 1核1G,100Mbps优质BGP,600GB月流量(超出限速1M),15GB SSD存储 |
| 96.2元 | 1核2G,100Mbps优质BGP,600GB月流量(超出限速1M),15GB SSD存储 |
一年付3.8折优惠码:12THBIRTHDAY 

{abtn icon="fa-diamond" color="#ff6800" href="https://my.yecaoyun.com/aff.php?aff=2415" radius="5px" content="点我前往野草云活动页"/}
{progress percentage="100%" color="#fff56b"/}
100MbpsBGP线路在国内实测下载速度是10M左右,比3M快了三四倍。就是一个月只有600GB流量,超过600GB就会被限速,我这一年用的过程中一个月最高用的还不到100GB了,正常建网站完全够用,如果用这搭梯子翻墙的话用的可能多一点。下载应用确实比国内服务器舒服,不用弄镜像源了,这可以直连github等代码仓库。
{progress percentage="80%" color="#fff56b"/}
一年里有两次断网超过12小时(都是小概率事件都被我撞上了),我看他们公告发了几次重启断网公告,这我倒是没察觉到。
财务系统被入侵了,强制给我重置了root密码并关机了 ::(黑线) 
香港地震给机房震断电了
目前我就这两家的服务器用的时长都超过一年了(内陆阿里云,海外野草云),其他家的没用过不做评价。

腾讯云、华为云、移动云等这些国内有名的也有很多便宜的服务器可以关注一下,但都是大陆空间都需要icp备案。
野草云除了隔几个月用十几分钟重启一下,没有啥毛病了,网速能接受,用来装xui最合适了,也是运营了12年应该不会跑路的。不过要极致稳定就选阿里云,要宽带和基本稳定就选野草云,香港离大陆也不算远,延迟不算高,给网站套个国内的CDN也可以缓解延迟。
如果有更便宜更具性价比的服务器欢迎留言:@(献花)
]]>
夜间模式
接下来需要编辑的文件以及相对Joe主题的文件路径:
/Joe/assets/js/Joe/assets/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}
{anote icon="music" href="https://lab.iarc.top/concert/" type="info" content="音乐厅"/}


Space空格键:暂停/播放音乐
上/下方向键:增加/减少音量
左/右方向键:上一曲/下一曲
播放列表的id,可以从音乐歌单分享的链接中获取,例如https://y.qq.com/n/ryqq/playlist/8668419170中,id为8668419170
网易云也同理。
播放列表的服务商,例如netease(网易云音乐),tencent(腾讯),kugou(酷狗),xiami(小米音乐),baidu(百度音乐)
支持URL参数 https://lab.iarc.top/concert/?id=+ id +&server= + server
例:
鸡你太美: https://lab.iarc.top/concert/?id=2762963245&server=netease
原作者开源地址:
{cloud title="原版地址" type="github" url="https://github.com/zhheo/HeoMusic" password=""/}
圆弧派二开地址:
{cloud title="二开地址" type="github" url="https://github.com/QingDi2/lab/tree/main/concert" password=""/}
二开新增功能:下载、标题、网易云歌单id输入框,其余原版功能未做删减。
全开源各位可以随便改
介绍页演示站:https://mxam.arcpi.cn
演示图:
源码都是静态文件,所以直接用cf pages网站托管平台免费建,当时vercel也可以的。
cf pages官网地址:戳我前往(无需魔法也能正常用)
选免费套餐就行,注册个号进去后也不用实名验证啥的,可以直接创建项目,然后把源码压缩包往里面一丢他会自动解压,最后cname解析一下域名就OK了
源码下载:
{hide}
{cloud title="程序介绍页" type="lz" url="https://xql.lanzouw.com/icQsm1xp287c" password=""/}
那个小程序源码好像都泛滥了,要是没泛滥的话留个言,过几天我再发出来吧
{/hide}