Selenium自动化测试进阶:元素操作与浏览器控制实战指南
1. 项目概述从“会写脚本”到“写好脚本”的跨越如果你已经用Selenium写过几个简单的自动化脚本比如打开百度、搜索个关键词那你可能已经体会到了它的便利。但很快你就会遇到新的烦恼为什么我的脚本总是莫名其妙地失败页面元素明明在那里脚本却说找不到浏览器弹了个警告框整个流程就卡住了或者在不同分辨率的机器上运行时元素位置对不上点击总是点偏。这些问题恰恰是区分“玩具脚本”和“生产级自动化”的关键所在。今天要聊的就是Selenium自动化测试中那些真正决定脚本稳定性和效率的核心操作——元素操作与浏览器操作。这不仅仅是学会几个API调用而是理解Web应用在动态环境下的行为逻辑并让你的脚本能够智能地与之交互。掌握了这些你的自动化代码才能从“勉强能用”变得“稳定可靠”真正成为测试工作中的利器而不是需要你时刻守在旁边“救火”的麻烦制造者。2. 核心思路模拟真实用户但要比用户更“聪明”很多新手会把自动化测试简单地理解为“用代码代替人手点鼠标”。这个理解只对了一半而且是比较浅显的那一半。更深层的思路是让你的脚本像一个经验丰富、耐心十足且永不疲倦的测试专家一样去操作浏览器。这意味着脚本不仅要能执行点击、输入等动作更要能处理各种意外情况适应不同的页面状态并做出合理的决策。举个例子一个真实用户看到页面加载慢他会等一会儿看到弹窗他会去关闭它发现按钮没反应他可能会刷新页面再试一次。你的Selenium脚本也需要具备这样的“智能”。这背后的核心支撑就是精准的元素操作和灵活的浏览器操作。元素操作关乎“找到谁”和“怎么操作它”浏览器操作则关乎“在什么环境下操作”。两者结合才能构建出健壮的自动化流程。我的经验是在开始编码前先在脑子里过一遍最挑剔的用户会怎么“折腾”这个页面然后让你的脚本去模拟并超越这种“折腾”。2.1 元素操作不止是click()和send_keys()当你用find_element定位到一个元素后真正的挑战才刚刚开始。直接调用click()可能因为元素被遮挡、不在视口内或者状态不可用而失败。交互前的状态检查一个健壮的操作应该在交互前先检查元素状态。例如点击一个按钮前可以判断它是否is_enabled()和is_displayed()。对于复选框input typecheckbox在点击前先通过is_selected()判断其当前状态再决定是否需要点击这样可以避免不必要的操作和状态混乱。from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.by import By # 等待元素可点击然后才点击 button WebDriverWait(driver, 10).until( EC.element_to_be_clickable((By.ID, “submit-btn”)) ) if button.is_enabled() and button.is_displayed(): button.click() else: print(“按钮不可用或不可见无法点击”) # 这里可以加入重试逻辑或错误处理高级交互动作链ActionChains对于简单的点击和输入上述方法足够。但对于拖拽、悬停、右键菜单、组合键等复杂交互就需要ActionChains出场了。它允许你将一系列动作编排成一个队列然后一次性执行这对于模拟用户的连续操作非常有用。from selenium.webdriver.common.action_chains import ActionChains from selenium.webdriver.common.keys import Keys # 示例在输入框输入内容后全选CtrlA然后复制CtrlC input_box driver.find_element(By.ID, “text-input”) actions ActionChains(driver) actions.click(input_box).send_keys(“Hello World”) actions.key_down(Keys.CONTROL).send_keys(“a”).key_up(Keys.CONTROL) # CtrlA actions.key_down(Keys.CONTROL).send_keys(“c”).key_up(Keys.CONTROL) # CtrlC actions.perform() # 执行所有动作注意ActionChains的perform()方法会执行队列中的所有动作。务必确保动作序列的逻辑正确并且目标元素在执行时处于合适的状态。有时在两个复杂动作之间加入短暂的等待time.sleep(0.5)是稳定性的小代价。2.2 浏览器操作掌控全局的导演如果说元素操作是演员的表演那么浏览器操作就是导演对舞台和剧本的控制。这部分决定了你的自动化脚本能在多复杂的场景下运行。窗口与标签页管理现代Web应用动辄打开新标签页或弹出窗口。你需要能够自如地切换。# 获取当前所有窗口的句柄 main_window driver.current_window_handle all_windows driver.window_handles # 点击一个会打开新标签页的链接 driver.find_element(By.LINK_TEXT, “在新窗口打开”).click() # 等待新窗口出现并切换过去 WebDriverWait(driver, 10).until(EC.number_of_windows_to_be(2)) for window_handle in driver.window_handles: if window_handle ! main_window: driver.switch_to.window(window_handle) break # 在新窗口操作... # 操作完毕后可以关闭新窗口并切回主窗口 driver.close() driver.switch_to.window(main_window)框架iframe与弹窗处理这是元素定位失败的常见原因。如果元素位于iframe内你必须先切换到对应的框架才能定位其中的元素。# 通过ID、Name或索引切换iframe driver.switch_to.frame(“iframe-id”) # 通过ID # driver.switch_to.frame(0) # 通过索引第一个iframe # 在iframe内操作元素 driver.find_element(By.ID, “inner-element”).click() # 操作完成后切回主文档 driver.switch_to.default_content()对于JavaScript生成的alert,confirm,prompt弹窗需要使用driver.switch_to.alert来处理。# 等待弹窗出现并获取其引用 WebDriverWait(driver, 5).until(EC.alert_is_present()) alert driver.switch_to.alert # 获取弹窗文本 print(alert.text) # 接受确定或解散取消 alert.accept() # 相当于点击“确定” # alert.dismiss() # 相当于点击“取消” # 如果是prompt还可以输入文本 # alert.send_keys(“Your input”) # alert.accept()Cookies与本地存储自动化测试经常需要模拟登录状态。与其每次输入用户名密码不如直接操作Cookies或LocalStorage。# 1. 获取所有cookies all_cookies driver.get_cookies() # 2. 添加一个特定的cookie常用于跳过登录 driver.add_cookie({‘name’: ‘session_token’, ‘value’: ‘abc123def456’, ‘domain’: ‘.example.com’}) # 添加后刷新页面通常就处于登录状态了 driver.refresh() # 操作LocalStorage (通过执行JavaScript) driver.execute_script(“window.localStorage.setItem(‘user_pref’, ‘dark_mode’);”)3. 等待策略自动化脚本的“节奏大师”这是Selenium自动化中最核心、也最容易出问题的部分。页面加载和元素渲染需要时间如果你的脚本动作太快在元素出现之前就去操作必然会失败。Selenium提供了三种等待方式用对了脚本稳如泰山用错了调试起来痛不欲生。3.1 强制等待time.sleep能不用就不用time.sleep(5)是最简单粗暴的等待。它让脚本无条件暂停指定时间。最大的问题是效率低下且不可靠。如果页面在2秒就加载完了你依然要傻等5秒如果网络慢5秒后元素还没出来脚本照样失败。它只在极少数明确需要固定停顿的场景下使用例如等待一个动画完成。3.2 隐式等待Implicit Wait设置全局超时通过driver.implicitly_wait(10)设置后在查找任何元素时如果元素没有立即出现WebDriver会轮询DOM默认每0.5秒直到元素被找到或超过设定的时间10秒。优点设置一次对后续所有find_element和find_elements调用都生效代码简洁。缺点它只对元素查找生效对元素的状态如可点击、可见无效。它是全局设置可能会在某些不需要等待的地方产生不必要的延迟。和显式等待混用时行为可能不符合预期最大等待时间可能是两者之和。3.3 显式等待Explicit Wait精准而优雅的解决方案显式等待是针对某个特定条件进行的等待是生产环境推荐的最佳实践。它使用WebDriverWait类和expected_conditions模块通常简写为EC。from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.by import By # 等待元素出现在DOM中并可见 element WebDriverWait(driver, 10).until( EC.visibility_of_element_located((By.ID, “dynamic-element”)) ) # 等待元素可被点击 clickable_element WebDriverWait(driver, 10).until( EC.element_to_be_clickable((By.CSS_SELECTOR, “.btn-primary”)) ) # 等待某个文本出现在元素中 WebDriverWait(driver, 10).until( EC.text_to_be_present_in_element((By.ID, “status”), “加载完成”) ) # 等待页面标题包含特定文字 WebDriverWait(driver, 10).until( EC.title_contains(“Dashboard”) )为什么显式等待更优条件精准你可以明确等待“元素可见”、“可点击”、“包含特定文本”等具体状态而不仅仅是存在于DOM。局部生效只影响需要等待的特定操作不影响脚本其他部分的执行速度。清晰明确代码明确表达了“在继续之前我必须等到某个条件成立”可读性更强。灵活性高你可以自定义等待条件通过函数或lambda表达式满足复杂场景。我的常用等待策略组合全局设置一个较短的隐式等待例如driver.implicitly_wait(3)作为查找元素的基础保障处理大多数简单的同步问题。关键步骤使用显式等待对于页面跳转、动态加载内容、按钮状态切换等关键点使用WebDriverWait配合具体的EC条件。这是脚本稳定性的主要支柱。几乎不用强制等待除非有非常特殊的理由如等待一个无法通过条件检测的固定时长后台任务。4. 实战封装一个健壮的元素操作工具函数理论说再多不如看一个实战例子。下面我封装一个自己项目中常用的safe_click函数它融合了等待、状态检查和重试机制。from selenium.common.exceptions import TimeoutException, StaleElementReferenceException, ElementClickInterceptedException from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.by import By import time def safe_click(driver, locator, byBy.ID, timeout10, retries2): 安全地点击一个元素包含等待、状态检查和重试逻辑。 参数: driver: WebDriver实例 locator: 定位器字符串如ID值、CSS选择器 by: 定位方式默认为By.ID timeout: 单次等待超时时间秒 retries: 失败重试次数 attempt 0 last_exception None while attempt retries: try: print(f“尝试点击元素 [{by}: {locator}]第 {attempt 1} 次尝试”) # 1. 等待元素可点击 element WebDriverWait(driver, timeout).until( EC.element_to_be_clickable((by, locator)) ) # 2. 尝试点击 element.click() print(“点击成功”) return True except (TimeoutException, StaleElementReferenceException, ElementClickInterceptedException) as e: last_exception e attempt 1 print(f“点击失败原因{type(e).__name__}”) if attempt retries: print(f“等待1秒后重试...”) time.sleep(1) # 重试前短暂等待 # 如果是元素过时Stale可能需要重新查找但EC已经处理了部分情况 # 这里可以加入更复杂的恢复逻辑比如刷新页面等 else: print(f“重试{retries}次后仍失败。”) # 可以在这里截图记录错误日志 # driver.save_screenshot(f“click_failed_{locator}.png”) raise last_exception # 抛出最后的异常 return False # 使用示例 # safe_click(driver, “submit-button”, By.ID) # safe_click(driver, “.login-form .btn”, By.CSS_SELECTOR, timeout15, retries3)这个函数的好处在于内置智能等待使用EC.element_to_be_clickable确保点击时元素是准备好的。异常处理捕获了常见的点击失败异常超时、元素过时、被拦截。重试机制在遇到临时性问题如短暂的渲染延迟、网络波动时自动重试提高了脚本的容错性。日志记录打印尝试过程便于调试。你可以根据这个模式进一步封装safe_send_keys安全输入、wait_for_element等待元素等工具函数逐步构建起自己的自动化测试工具库。5. 浏览器操作的进阶技巧与性能考量掌握了基础操作后我们来看看如何让浏览器操作更高效、更符合测试需求。5.1 窗口尺寸与截图视觉验证与响应式测试自动化测试不仅仅是功能测试有时也需要进行简单的视觉验证或确保页面在不同尺寸下的布局正常。# 设置浏览器窗口大小 driver.set_window_size(1920, 1080) # 设置为桌面全高清 driver.set_window_size(375, 667) # 设置为iPhone 6/7/8尺寸 # 获取当前窗口尺寸 size driver.get_window_size() print(f“窗口宽度{size[‘width’]}高度{size[‘height’]}”) # 全屏截图 driver.save_screenshot(“full_page.png”) # 对特定元素截图需要先定位到该元素 element driver.find_element(By.ID, “chart-container”) element.screenshot(“chart.png”) # 这个方法非常实用元素级截图在验证UI组件如图表、验证码图片区域的渲染结果时特别有用。5.2 执行JavaScript突破Selenium的局限Selenium的execute_script方法是一把瑞士军刀可以让你直接与页面的JavaScript环境交互完成一些WebDriver API无法直接实现的操作。# 1. 滚动页面 # 滚动到页面底部 driver.execute_script(“window.scrollTo(0, document.body.scrollHeight);”) # 滚动到特定元素 element driver.find_element(By.ID, “footer”) driver.execute_script(“arguments[0].scrollIntoView(true);”, element) # true表示与顶部对齐 # 2. 修改元素属性或样式用于调试或处理特殊元素 driver.execute_script(“document.getElementById(‘readonly-input’).removeAttribute(‘readonly’);”) driver.execute_script(“arguments[0].style.border ‘3px solid red’;”, element) # 高亮元素 # 3. 获取或设置浏览器存储 local_storage_value driver.execute_script(“return window.localStorage.getItem(‘user_key’);”) driver.execute_script(“window.sessionStorage.setItem(‘temp_data’, ‘123’);”) # 4. 处理复杂的日期选择器等组件 # 有些组件基于JS直接设置input的value可能不触发事件 date_input driver.find_element(By.ID, “date-picker”) driver.execute_script(“arguments[0].value ‘2023-10-27’; arguments[0].dispatchEvent(new Event(‘change’));”, date_input)注意虽然execute_script很强大但应谨慎使用。过度依赖它会让你的测试脚本与具体的前端实现JS紧密耦合如果前端代码重构你的测试脚本可能更容易失效。优先使用标准的WebDriver API。5.3 性能日志与网络控制基于DevTools Protocol对于现代浏览器Chrome、Edge、Firefox可以通过启用性能日志或利用DevTools Protocol进行更底层的控制这对性能测试或模拟弱网环境很有帮助。from selenium.webdriver.common.desired_capabilities import DesiredCapabilities # 启用性能日志Chrome caps DesiredCapabilities.CHROME caps[‘goog:loggingPrefs’] { ‘performance’: ‘ALL’ } driver webdriver.Chrome(desired_capabilitiescaps) # 之后可以获取网络请求日志 logs driver.get_log(‘performance’) for entry in logs: # 解析entry[‘message’]是一个JSON字符串可以提取URL、状态码、请求类型等 pass # 更高级的网络模拟通常结合第三方库如 browsermob-proxy 或直接使用CDP # 例如通过CDP模拟慢速3G网络 driver.execute_cdp_cmd(‘Network.emulateNetworkConditions’, { ‘offline’: False, ‘latency’: 150, # 延迟毫秒 ‘downloadThroughput’: 1.6 * 1024 * 1024 / 8, # 下载吞吐量字节/秒 ‘uploadThroughput’: 0.75 * 1024 * 1024 / 8, # 上传吞吐量 })6. 常见问题排查与脚本调试心得即使掌握了所有技巧编写自动化脚本时依然会遇到各种“坑”。下面是我总结的一些常见问题及排查思路。6.1 元素定位失败为什么就是找不到这是最频繁出现的问题。可以按照以下清单排查问题现象可能原因排查与解决方案NoSuchElementException1. 定位器写错了。2. 页面有iframe元素在框架内。3. 元素是动态生成的还未加载出来。4. 页面有多个匹配的元素find_element只返回第一个但可能不是你想要的。1.核对定位器在浏览器开发者工具F12的Console里用$$(“你的CSS选择器”)或$x(“你的XPath”)验证。2.检查iframe查看元素是否在iframe内需要先switch_to.frame。3.增加显式等待使用EC.presence_of_element_located或EC.visibility_of_element_located。4.使用find_elements检查返回列表的长度和内容调整定位器使其更精确。StaleElementReferenceException元素过时你之前找到的元素对应的DOM节点已经被页面刷新或重新渲染了常见于单页应用SPA。1.重新查找元素在操作前重新执行find_element。2.使用显式等待WebDriverWait内部已经处理了部分过时元素的问题。3.封装重试逻辑像上面的safe_click函数一样在捕获到此异常时进行重试。ElementNotInteractableException元素存在但不可交互如被遮挡、不可见、disabled状态。1.检查元素状态用is_displayed()和is_enabled()判断。2.滚动到元素使用driver.execute_script(“arguments[0].scrollIntoView(true);”, element)。3.检查遮挡物是否有模态框modal、弹窗覆盖了目标元素。脚本在本地运行成功在CI/CD服务器上失败1. 环境差异浏览器版本、驱动版本。2. 服务器资源不足页面加载慢。3. 无头headless模式下的差异。1.固定版本在CI环境中使用与本地一致的、明确的浏览器和WebDriver版本。2.增加超时时间为显式等待设置更长的超时如30秒。3.添加更多日志和截图在关键步骤和失败时截图便于远程诊断。4.考虑显式等待的条件在headless模式下某些元素渲染或动画可能不同。6.2 脚本运行不稳定Flaky Tests脚本时而成功时而失败是最令人头疼的问题。除了上述定位问题还有以下原因异步操作未完成页面上的Ajax请求或JavaScript动画还没结束脚本就进行了下一步操作。解决不要用固定等待改用更智能的等待条件。例如等待某个代表加载完成的元素出现或者等待某个元素的特定属性如class发生变化。# 等待一个加载动画消失 WebDriverWait(driver, 30).until( EC.invisibility_of_element_located((By.ID, “loading-spinner”)) )测试数据依赖测试用例依赖于特定的前置数据状态而之前的测试可能修改了它。解决每个测试用例应该是独立的。使用setUp和tearDown方法或pytest的fixture来准备和清理测试数据确保用例执行前后环境一致。并发问题在并行执行测试时多个测试可能操作同一份数据或产生冲突。解决使用独立的测试账号、隔离的测试数据库或通过其他方式如UUID生成唯一的数据标识避免冲突。6.3 我的调试工具箱暂停大法time.sleep虽然不推荐用于生产脚本但在调试时在可疑的步骤前插入一个time.sleep(5)然后手动观察浏览器状态是快速定位问题的最直接方法。截图save_screenshot在关键步骤后如登录后、提交前和异常捕获时截图。一张图片包含的信息量远超日志文字。打印页面源码或元素HTML当定位器失效时打印出driver.page_source的一部分或者打印元素的element.get_attribute(‘outerHTML’)可以帮你确认你看到的和脚本“看到”的是否一致。使用浏览器的开发者工具在脚本运行期间尤其是time.sleep暂停时手动打开开发者工具检查元素、网络请求和Console输出这是前端问题排查的黄金手段。详细的日志记录为你的测试框架配置详细的日志级别如DEBUG记录每一步操作、定位器、等待结果等。当问题发生时日志时间线是还原现场的关键。7. 从操作到框架构建可维护的自动化测试掌握了扎实的元素和浏览器操作后你的眼光应该从单个脚本转移到整个测试套件的组织和维护上。一个好的自动化测试不仅要能运行还要易读、易维护、易扩展。1. 页面对象模型Page Object Model, POM这是UI自动化测试的经典设计模式。其核心思想是将每个页面或页面中的重要组件封装成一个类页面的元素定位器和基本操作作为这个类的方法。测试用例则通过调用这些页面对象的方法来完成操作。优点代码复用元素定位和基础操作只写一次。易于维护当页面UI变化时通常只需要修改对应的页面对象类而不需要修改大量测试用例。可读性强测试用例读起来像自然语言例如login_page.enter_username(“admin”).enter_password(“123”).click_login()。2. 数据驱动测试将测试数据如用户名、密码、搜索关键词从测试脚本中分离出来存储在外部文件如JSON、YAML、Excel、CSV或数据库中。测试脚本读取这些数据来执行测试。这使得添加新的测试用例变得非常简单只需增加数据行即可。3. 配置管理将浏览器类型、基础URL、超时时间、登录凭证等配置信息提取到配置文件如config.ini或config.yaml中。这样在不同环境开发、测试、生产下运行测试只需切换配置文件而无需修改代码。4. 测试报告与日志集成使用如pytest-html、Allure等工具生成美观详尽的测试报告。结合详细的日志记录在测试失败时能快速定位问题根源。把这些最佳实践结合起来你的Selenium自动化就不再是零散的脚本而是一个结构清晰、职责分明、易于协作的测试框架。这会让你的自动化工作事半功倍也是从自动化脚本编写者迈向测试开发工程师的关键一步。

相关新闻

ARM微控制器UART扩展实战:基于SC16IS752的SPI转双串口设计

ARM微控制器UART扩展实战:基于SC16IS752的SPI转双串口设计

1. 项目概述与核心价值在嵌入式硬件开发中,我们经常遇到一个经典难题:主控芯片(比如ARM Cortex-M系列)的串行接口资源是有限的,通常只有一两个UART。但项目需求却往往需要连接多个使用RS-232、RS-485甚至红外IrDA协议的…

2026/6/21 18:08:03阅读更多 →
LAN938x以太网交换芯片固件升级全攻略:从UART到网络OTA

LAN938x以太网交换芯片固件升级全攻略:从UART到网络OTA

1. 项目概述:为什么LAN938x的固件升级值得深究?如果你手头有基于Microchip LAN938x系列以太网交换芯片的设备,无论是工业网关、网络录像机还是某种定制嵌入式设备,那么固件升级这件事,迟早会找上门。LAN938x作为一款集…

2026/6/21 18:08:03阅读更多 →
Ubuntu 14.04下Flask生产部署:uWSGI+Nginx完整实践

Ubuntu 14.04下Flask生产部署:uWSGI+Nginx完整实践

1. 这不是“又一篇部署教程”,而是生产级 Flask 服务落地的完整思维链你搜到这个标题时,大概率正卡在某个具体环节:uWSGI 启动后进程立刻退出、Nginx 返回 502 Bad Gateway、Flask 应用里request.form总是空、或者更糟——在 Ubuntu 14.04 上…

2026/6/21 18:08:03阅读更多 →
终极解决方案:如何让Obsidian笔记摆脱平台束缚,实现自由迁移?

终极解决方案:如何让Obsidian笔记摆脱平台束缚,实现自由迁移?

终极解决方案:如何让Obsidian笔记摆脱平台束缚,实现自由迁移? 【免费下载链接】obsidian-export Rust library and CLI to export an Obsidian vault to regular Markdown 项目地址: https://gitcode.com/gh_mirrors/ob/obsidian-export …

2026/6/21 21:08:24阅读更多 →
分布式光纤传感与贝叶斯反演在预应力混凝土监测中的应用

分布式光纤传感与贝叶斯反演在预应力混凝土监测中的应用

1. 预应力混凝土结构健康监测技术概述预应力混凝土结构在现代桥梁和建筑中广泛应用,其核心是通过预先施加的压应力抵消使用荷载产生的拉应力。然而,预应力筋断裂作为最危险的隐蔽性损伤之一,传统检测方法难以实现早期预警。分布式光纤传感技术…

2026/6/21 21:08:24阅读更多 →
Gemini 3.5 Flash深度解析:100万Token轻量推理引擎实战指南

Gemini 3.5 Flash深度解析:100万Token轻量推理引擎实战指南

1. 项目概述:这不是一次普通升级,而是Google AI推理范式的悄然转移Gemini 3.5 Flash来了——这个标题在开发者社区刷屏时,我正用它跑完一个实时多模态会议纪要生成任务。整个过程从语音转文字、提取关键决策点、自动生成待办事项,…

2026/6/21 21:08:24阅读更多 →
AutoGLM手机AI助手:普通电脑与手机本地部署实战指南

AutoGLM手机AI助手:普通电脑与手机本地部署实战指南

1. 为什么“普通电脑也能用”不是营销话术,而是技术落地的关键分水岭AutoGLM本地部署——这个标题里藏着一个被多数人忽略的真相:它根本不是另一个“跑在服务器上的大模型玩具”,而是一次针对真实用户硬件条件的精准适配。我去年帮三位朋友部…

2026/6/21 21:08:24阅读更多 →
MapSR:基于视觉基础模型的土地覆盖图语义超分辨率技术详解

MapSR:基于视觉基础模型的土地覆盖图语义超分辨率技术详解

1. 项目概述:当土地覆盖图遇上“高清放大镜”作为一名长期与遥感影像和地理信息数据打交道的从业者,我经常遇到一个令人头疼的问题:手头只有一张分辨率粗糙的土地覆盖图,却需要用它来分析精细的地物边界、评估小尺度的生态变化&am…

2026/6/21 21:08:24阅读更多 →
Debian 10下部署TigerVNC远程桌面实战指南

Debian 10下部署TigerVNC远程桌面实战指南

1. 项目概述:为什么在 Debian 10 上亲手部署 VNC 是一项值得投入时间的基础能力VNC(Virtual Network Computing)不是某个特定软件,而是一套成熟的远程图形桌面协议标准。它允许你通过网络,在一台设备上操作另一台设备的…

2026/6/21 21:03:24阅读更多 →
【人工智能】一文搞定到底什么是智能体

【人工智能】一文搞定到底什么是智能体

【人工智能】一文搞定到底什么是智能体 一文搞定到底什么是智能体【人工智能】一文搞定到底什么是智能体一. LM,WorkFlow,Agent分别有什么么不同二. Agent的思考过程是怎样的三. Agent的五个核心部分1)LLM2)Prompt3)Me…

2026/6/21 0:00:40阅读更多 →
嵌入式GUI控件实战:ROTARY、SCROLLBAR、SLIDER原理与应用

嵌入式GUI控件实战:ROTARY、SCROLLBAR、SLIDER原理与应用

1. 嵌入式GUI控件:从原理到实战的深度解析在嵌入式系统开发中,图形用户界面(GUI)的设计与实现往往是项目从“能用”到“好用”的关键一跃。不同于资源充沛的PC或移动平台,嵌入式设备的GUI需要在有限的CPU性能、内存空间…

2026/6/21 0:00:40阅读更多 →
Google AI Studio 300美元额度的真相与实战指南

Google AI Studio 300美元额度的真相与实战指南

1. 这300美金不是“送钱”,而是Google埋下的第一道技术门槛 你看到标题里那个醒目的“$300美金”时,第一反应可能是:又一个免费额度?领完就完事?我亲手试过——这300美金根本不是红包,而是一张入场券&…

2026/6/21 0:00:40阅读更多 →
【人工智能】一文搞定到底什么是智能体

【人工智能】一文搞定到底什么是智能体

【人工智能】一文搞定到底什么是智能体 一文搞定到底什么是智能体【人工智能】一文搞定到底什么是智能体一. LM,WorkFlow,Agent分别有什么么不同二. Agent的思考过程是怎样的三. Agent的五个核心部分1)LLM2)Prompt3)Me…

2026/6/21 0:00:40阅读更多 →
嵌入式GUI控件实战:ROTARY、SCROLLBAR、SLIDER原理与应用

嵌入式GUI控件实战:ROTARY、SCROLLBAR、SLIDER原理与应用

1. 嵌入式GUI控件:从原理到实战的深度解析在嵌入式系统开发中,图形用户界面(GUI)的设计与实现往往是项目从“能用”到“好用”的关键一跃。不同于资源充沛的PC或移动平台,嵌入式设备的GUI需要在有限的CPU性能、内存空间…

2026/6/21 0:00:40阅读更多 →
Google AI Studio 300美元额度的真相与实战指南

Google AI Studio 300美元额度的真相与实战指南

1. 这300美金不是“送钱”,而是Google埋下的第一道技术门槛 你看到标题里那个醒目的“$300美金”时,第一反应可能是:又一个免费额度?领完就完事?我亲手试过——这300美金根本不是红包,而是一张入场券&…

2026/6/21 0:00:40阅读更多 →