news 2026/6/20 21:34:23

从零掌握Playwright自动化测试:环境搭建、核心API与实战避坑指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
从零掌握Playwright自动化测试:环境搭建、核心API与实战避坑指南

1. 项目概述:为什么是Playwright?

如果你正在为Web应用的UI自动化测试发愁,或者刚从Selenium的“坑”里爬出来,想找一个更现代、更稳定的工具,那么Playwright绝对值得你花时间研究。我最初接触它,是因为一个持续了快两年的老项目——一个复杂的SaaS后台管理系统,前端框架从Vue 2升级到Vue 3,还夹杂着大量的动态加载和WebSocket实时更新。用传统的Selenium WebDriver,光是处理各种异步等待和元素定位的稳定性问题,就足以让测试脚本变得脆弱不堪,维护成本高得吓人。直到团队里有人尝试了Playwright,测试用例的通过率从70%左右直接拉到了95%以上,我才真正意识到,工具选型对自动化测试的成败有多关键。

Playwright不是一个凭空出现的框架,你可以把它看作是自动化测试领域一次“体验驱动”的进化。它由微软开源并持续维护,核心目标是解决Web UI自动化中的几个老大难问题:跨浏览器支持的一致性、对现代Web技术(如单页应用SPA、WebSocket、Service Worker)的原生支持,以及最重要的——稳定性。与Selenium需要为不同浏览器维护不同的驱动(Driver)不同,Playwright直接通过其自带的浏览器二进制文件进行通信,这意味着它和浏览器之间的“对话”更直接、更高效,也从根本上减少了因驱动版本不匹配导致的诡异问题。

对于刚入门的朋友,可能会问:市面上还有Cypress、Puppeteer,为什么选Playwright?我的体会是,Playwright在“全能性”上做得更均衡。Cypress在开发者体验和调试上很棒,但它的架构决定了其更侧重于同源测试,对于需要多标签页、多域名跳转的复杂场景有些力不从心。Puppeteer是Chrome团队的亲儿子,对Chrome/Chromium的支持无与伦比,但跨浏览器(Firefox, WebKit)的支持是后来才加上,且一度不如Playwright成熟。而Playwright从设计之初就平等地支持Chromium、Firefox和WebKit(Safari的引擎),并且提供了统一的、极其强大的API,让你写一份脚本,就能在三大浏览器引擎上稳定运行。这对于需要确保跨浏览器兼容性的项目来说,价值巨大。

所以,这篇教程的目标很明确:带你绕过我踩过的那些坑,用最快、最稳的方式,从零开始搭建一个可用的Playwright自动化测试环境,并写出你的第一个真正能跑起来的测试脚本。我们不谈空泛的理论,只聚焦于“怎么做”和“为什么这么做”,让你学完就能立刻用起来。

2. 环境准备与核心工具链解析

工欲善其事,必先利其器。Playwright的环境搭建比想象中简单,但其中有一些关键选择,会直接影响你后续的开发体验和脚本稳定性。

2.1 编程语言选择:为什么推荐Python?

Playwright支持多种语言绑定,包括JavaScript/TypeScript、Python、.NET和Java。对于入门者,我强烈推荐从Python开始。原因有三:第一,语法简洁,学习曲线平缓,你可以更专注于学习Playwright本身的API,而不是和复杂的语言特性搏斗;第二,生态丰富,Python在数据处理、报告生成等方面有大量成熟的库,可以轻松与测试框架集成;第三,社区活跃,遇到问题时,无论是Playwright的Python API问题还是Python本身的问题,都更容易找到解决方案。

当然,如果你的团队前端技术栈是Node.js,或者项目本身就是用TypeScript开发的,那么选择TypeScript版本也能获得非常好的类型提示和开发体验。但对于大多数测试工程师或刚转型自动化的同学来说,Python是性价比最高的选择。

注意:无论选择哪种语言,Playwright的核心概念和API设计都是高度一致的。学会一种,再切换到另一种语言绑定,成本非常低。

2.2 安装Playwright:一步到位与精细化控制

安装Playwright主要有两种方式:通过包管理工具安装库,然后安装浏览器;或者使用Playwright CLI工具。对于新手,我推荐使用CLI工具,因为它能帮你处理很多琐事。

打开你的终端(命令行),执行以下命令来安装Playwright的Python包:

pip install playwright

这条命令会安装Playwright的核心库。接下来,你需要安装浏览器。Playwright不会使用你系统里已有的Chrome或Firefox,而是会下载它自己管理的、经过兼容性测试的浏览器版本。这是保证跨环境一致性的关键。

安装所有支持的浏览器(Chromium, Firefox, WebKit):

playwright install

这条命令会下载大约几百MB的浏览器二进制文件到本地缓存中。如果你网络环境不太好,或者暂时只需要测试Chrome,可以使用:

playwright install chromium

只安装Chromium。在实际项目中,我建议至少安装Chromium和Firefox,因为这是最常见的两大内核。

这里有一个非常重要的实操心得:务必在项目初期就统一团队成员的浏览器安装版本。你可以在package.json(对于Node.js)或requirements.txt(对于Python)中固定playwright的版本,并且约定大家都使用playwright install来安装浏览器,而不是从系统路径调用。这样可以完美复现“在我机器上是好的”这种问题。

2.3 编辑器与调试环境配置

写自动化脚本,一个好用的编辑器能事半功倍。我首推Visual Studio Code(VS Code),因为它对Playwright有官方扩展支持。

  1. 在VS Code中搜索并安装“Playwright Test for VSCode”扩展。
  2. 安装后,你会在侧边栏看到一个专门的Playwright图标。这个扩展提供了太多便利功能:
    • 测试资源管理器:以树形结构展示所有测试用例,可以单独运行、调试某个用例或整个文件。
    • 代码透镜:在测试函数上方直接显示“Run Test”和“Debug Test”按钮。
    • 录制功能:虽然我不建议过度依赖录制,但对于快速生成一些基础操作脚本或学习API,它非常有用。
    • Trace Viewer集成:当测试失败时,可以一键查看详细的执行追踪,包括每一步的截图、网络请求、控制台日志,这是Playwright最强大的调试利器之一。

配置好编辑器后,我建议你立刻创建一个简单的测试文件来验证环境。在你的项目目录下,创建一个名为test_demo.py的文件:

from playwright.sync_api import sync_playwright def test_visit_baidu(): with sync_playwright() as p: # 选择浏览器,这里用Chromium browser = p.chromium.launch(headless=False) # headless=False 表示打开浏览器界面,方便观察 page = browser.new_page() page.goto("https://www.baidu.com") # 简单的断言:页面标题应该包含“百度” assert "百度" in page.title() # 截图保存,这是很好的习惯 page.screenshot(path="baidu_homepage.png") browser.close() if __name__ == "__main__": test_visit_baidu() print("测试通过!")

运行这个脚本python test_demo.py。如果一切正常,你会看到一个浏览器窗口打开,访问百度首页,然后关闭,并在控制台看到“测试通过!”的输出,同时当前目录下会生成一张截图。恭喜,你的Playwright环境已经就绪!

3. 核心API与元素操作实战

环境搭好了,我们来真正动手写代码。Playwright的API设计非常直观,核心对象就那几个:BrowserBrowserContextPageLocator。理解它们的关系,是写出健壮脚本的基础。

3.1 理解核心对象模型

你可以把整个模型想象成一次真实的浏览器会话:

  • Browser:对应一个浏览器实例,比如你打开了Chrome程序。通过launch()方法启动。
  • BrowserContext:这是一个非常重要的概念,对应一个“独立的浏览器会话”。每个Context拥有独立的cookie、缓存、权限设置。你可以用它来实现测试之间的隔离,或者模拟多个用户同时登录。一个Browser可以创建多个Context。
  • Page:对应一个浏览器标签页。我们绝大部分操作都是在Page对象上进行的,比如导航、点击、输入。一个Context可以拥有多个Page(多标签页)。
  • Locator:这是Playwright的“王牌”之一。它代表一个用于定位页面元素的“选择器”。Locator是惰性求值的,并且具有自动重试和等待机制,这是其稳定性的核心。

一个典型的启动流程代码如下:

from playwright.sync_api import sync_playwright with sync_playwright() as p: # 启动浏览器 browser = p.chromium.launch(headless=False) # 创建一个上下文(会话) context = browser.new_context() # 在上下文中打开一个新页面 page = context.new_page() # ... 在这里进行你的测试操作 ... # 关闭上下文和浏览器 context.close() browser.close()

使用with语句可以确保资源被正确关闭,即使测试中途出错。

3.2 元素定位:告别脆弱的XPath

元素定位是UI自动化的基石,也是脚本最容易“失效”的地方。Playwright提供了多种定位器,优先级我建议如下:

  1. get_by_role():首选。这是最语义化、最稳定的方式。它通过元素的ARIA角色(button, heading, textbox等)和可访问名(Accessible Name)来定位。

    # 定位一个名为“搜索”的按钮 page.get_by_role("button", name="搜索").click() # 定位一个占位符是“请输入用户名”的文本框 page.get_by_role("textbox", name="请输入用户名").fill("my_username")

    这种方式几乎不受前端CSS类名或ID变更的影响,只要产品功能不变,定位器就稳定。

  2. get_by_text() 和 get_by_label():也非常可靠。get_by_text通过元素内的可见文本来定位,get_by_label通过关联的<label>标签文本来定位表单元素。

    # 点击页面上显示为“提交”的文本元素 page.get_by_text("提交").click() # 定位标签为“邮箱:”的输入框 page.get_by_label("邮箱:").fill("test@example.com")
  3. get_by_placeholder(), get_by_title(), get_by_alt_text():针对有特定属性的元素。

  4. CSS Selector 和 XPath:作为最后的手段。当以上语义化方式都无法定位时,才考虑使用。Playwright支持标准的CSS选择器和XPath语法。尽量避免使用复杂的、依赖页面结构的XPath,比如//div[3]/div[2]/span,这种定位器在前端结构调整时必挂。

    # 使用CSS选择器 page.locator(".primary-btn.submit").click() # 使用XPath(谨慎使用) page.locator("//button[@data-testid='submit-button']").click()

    如果必须用,尽量结合前端同学添加的测试专用属性,如># 推荐做法 search_box = page.get_by_role("textbox", name="搜索") search_box.click() # Locator会等待元素可点击 search_box.fill("Playwright") # 不推荐(旧版或某些教程中的)做法 page.click("input[name='q']") # 直接使用选择器字符串,等待逻辑可能不同

    3.3 常用交互操作详解

    定位到元素后,就是与之交互。Playwright的API非常直观:

    • 点击locator.click()
    • 输入/填充locator.fill(value)会先清空再输入。locator.type(value)是模拟键盘逐个输入。
    • 勾选复选框/单选框locator.check()locator.uncheck()
    • 选择下拉框locator.select_option(value)locator.select_option(label=label)
    • 上传文件locator.set_input_files(file_path),支持单个文件、多个文件。
    • 鼠标悬停locator.hover()
    • 键盘操作page.keyboard.type(“Hello”),page.keyboard.press(“Enter”)

    一个模拟登录的完整例子:

    def test_login(page): # 假设page是通过Pytest等框架提供的 page.goto("https://example.com/login") # 使用role定位,非常稳定 page.get_by_role("textbox", name="用户名").fill("testuser") page.get_by_role("textbox", name="密码").fill("secretpassword") page.get_by_role("button", name="登录").click() # 等待登录成功后的页面元素出现 expect(page.get_by_text("欢迎回来,testuser")).to_be_visible()

    4. 等待策略:解决异步加载问题的银弹

    现代Web应用大量使用Ajax、SPA路由,数据是异步加载的。传统的“死等”(time.sleep(5))或“隐式等待”是测试脚本不稳定的罪魁祸首。Playwright提倡显式的、基于状态的等待

    4.1 自动等待:Locator的内置魔法

    当你对Locator执行操作(如click,fill)或断言时,Playwright会自动执行一系列检查,直到元素满足条件为止。例如:

    • locator.click():会等待该元素被附加到DOM、可见、可交互(例如不被其他元素遮挡)、稳定(例如不再有动画)后,才执行点击。
    • locator.fill():同样会等待元素可编辑。

    这意味着在大多数情况下,你不需要手动写等待,直接操作即可。这是Playwright相比Selenium的一个巨大优势。

    4.2 显式等待:应对复杂场景

    尽管自动等待很强大,但有些场景仍需手动控制:

    1. 等待导航page.goto(url)本身会等待页面load事件。但对于SPA,页面load后内容可能还没加载完。你可以等待某个特定元素出现:

      page.goto("https://example.com/dashboard") # 等待仪表盘上的关键元素加载出来 page.wait_for_selector(".dashboard-widget", state="visible") # 或者使用更语义化的locator等待 page.get_by_text("本月数据统计").wait_for(state="visible")
    2. 等待网络请求:这是Playwright的杀手级功能。你可以等待某个特定的API请求完成并获取其响应,非常适合测试前后端交互。

      # 在点击“搜索”按钮前,先“监听”将要发出的请求 with page.expect_response("**/api/search*") as response_info: page.get_by_role("button", name="搜索").click() response = response_info.value # 断言响应状态码是200 assert response.ok # 可以进一步解析响应体,做数据断言 response_body = response.json() assert response_body["total"] > 0
    3. 等待函数条件:最灵活的等待方式,使用page.wait_for_function()

      # 等待页面JS中的某个变量变为特定值 page.wait_for_function("window.chartDataLoaded === true") # 等待某个元素的数量满足条件 page.wait_for_function("""() => document.querySelectorAll('.list-item').length >= 10""")

    重要避坑技巧:尽量避免使用page.wait_for_timeout(3000)这种固定等待。它会让测试变慢且不可靠。如果非要用,问问自己:我到底在等什么?是等一个元素?一个请求?还是一个JS状态?然后用对应的显式等待方法替代它。

    5. 高级特性与框架集成

    掌握了基础操作,我们可以让测试脚本更健壮、更易维护,并集成到CI/CD流程中。

    5.1 使用Pytest测试框架

    虽然可以直接写Python脚本运行Playwright,但集成像Pytest这样的测试框架会带来巨大好处:夹具(Fixture)管理、参数化测试、丰富的断言、测试报告等。

    首先安装Pytest和Playwright的Pytest插件:

    pip install pytest pytest-playwright

    创建一个测试文件test_login.py

    import pytest from playwright.sync_api import Page, expect # 使用pytest-playwright提供的page fixture def test_login_with_valid_credentials(page: Page): page.goto("https://example.com/login") page.get_by_label("用户名").fill("admin") page.get_by_label("密码").fill("admin123") page.get_by_role("button", name="登录").click() # 使用Playwright的断言库,它内置了智能等待 expect(page).to_have_url("https://example.com/dashboard") expect(page.get_by_text("登录成功")).to_be_visible() # 参数化测试:测试多组登录数据 @pytest.mark.parametrize("username, password, expected_error", [ ("", "admin123", "用户名不能为空"), ("admin", "wrong", "密码错误"), ]) def test_login_with_invalid_credentials(page: Page, username, password, expected_error): page.goto("https://example.com/login") page.get_by_label("用户名").fill(username) page.get_by_label("密码").fill(password) page.get_by_role("button", name="登录").click() expect(page.get_by_text(expected_error)).to_be_visible()

    使用pytest test_login.py -v来运行测试。page这个fixture由pytest-playwright插件自动提供,它帮你管理了浏览器的启动和关闭,无需手动写with sync_playwright()

    5.2 夹具(Fixture)与全局配置

    Pytest的夹具可以帮你初始化测试数据、登录状态等。一个常见的需求是,每个测试用例都需要一个已登录的状态。我们可以创建一个自定义夹具:

    conftest.py文件中:

    import pytest from playwright.sync_api import Page, BrowserContext @pytest.fixture(scope="session") def browser_context_args(browser_context_args): # 全局的浏览器上下文参数,例如视口大小、忽略HTTPS错误 return { **browser_context_args, "viewport": {"width": 1920, "height": 1080}, "ignore_https_errors": True, # 对于测试环境有用 } @pytest.fixture def logged_in_page(page: Page): """返回一个已登录的页面对象""" # 执行登录逻辑 page.goto("https://example.com/login") page.get_by_label("用户名").fill("test_user") page.get_by_label("密码").fill("test_pass") page.get_by_role("button", name="登录").click() # 等待登录成功,确保返回的是一个确定登录状态的页面 expect(page.get_by_text("我的主页")).to_be_visible() # 为了确保登录状态持久化,可以将存储的状态保存下来,但这里简单返回page # 更佳实践是:登录一次,保存storage_state,然后每个测试加载它 return page # 更佳实践:使用storage_state保存登录态 @pytest.fixture(scope="session") def browser_context_args(browser_context_args, playwright): # 先创建一个上下文登录,并保存状态 browser = playwright.chromium.launch(headless=True) context = browser.new_context() page = context.new_page() page.goto("https://example.com/login") # ... 登录操作 ... # 保存登录状态(cookies, local storage等) context.storage_state(path=".auth/state.json") browser.close() # 告诉后续所有测试,使用这个保存的状态来初始化上下文 return { **browser_context_args, "storage_state": ".auth/state.json" }

    这样,你的测试用例就可以直接使用干净的、已登录的页面了。

    5.3 录制与代码生成:快速起步的利器

    Playwright提供了一个强大的代码录制工具。虽然我不建议长期依赖录制生成的代码(因为通常不够健壮和结构化),但它对于快速探索一个网站的交互流程,或者为复杂操作生成代码骨架,非常有帮助。

    运行命令启动录制器,并打开一个浏览器:

    playwright codegen https://example.com

    然后你在浏览器里的所有操作,都会被实时转换成你选择的编程语言(Python、JavaScript等)的代码,显示在旁边的窗口中。你可以把这些代码复制出来,作为你编写正式测试脚本的起点,然后对其进行重构和优化,比如将选择器替换成更稳定的get_by_role,添加明确的断言等。

    6. 常见问题排查与调试技巧实录

    即使有了好工具,写自动化测试也难免遇到问题。以下是几个我踩过坑的典型场景和解决方法。

    6.1 元素定位不到:最常见的问题

    现象:脚本报错TimeoutError: Timeout 30000ms exceeded.,提示定位不到元素。

    排查思路

    1. 检查页面是否加载完成:在定位前加一个page.wait_for_load_state(‘networkidle’),等待网络基本空闲。或者直接等待某个更稳定的顶层元素。
    2. 检查选择器是否正确:使用Playwright Inspector或浏览器开发者工具验证。
      • 运行脚本时加上PWDEBUG=1环境变量:PWDEBUG=1 pytest test.py。这会让脚本以“调试模式”运行,浏览器不会关闭,并且会打开Playwright Inspector,你可以实时查看页面、查看生成的定位器、甚至录制新操作。
      • 在测试中临时加入page.pause(),脚本会在此处暂停并打开Inspector。
    3. 检查元素是否在iframe或shadow DOM中:这是两个常见的“陷阱”。
      • iframe:你需要先切换到iframe的Frame对象内。
        # 通过iframe的name或URL定位 frame = page.frame(name="login-frame") # 或者 page.frame(url=“**/login”) # 然后在frame对象上操作 frame.get_by_role("textbox", name="用户名").fill(“user”)
      • Shadow DOM:Playwright可以穿透Shadow DOM。使用locator.locator()进行链式定位,或者CSS选择器中的>>>/deep/(已废弃,但Playwright有自己方式)。
        # 假设有一个自定义元素 <my-component> # 直接定位其shadow DOM内的按钮 page.locator("my-component").locator("button").click()
    4. 检查元素是否可见/可交互:有时元素在DOM中,但被CSS隐藏(display: none)或者被其他元素遮挡。Playwright的自动等待会处理可见性,但如果等待超时,你需要检查前端样式或布局。

    6.2 异步操作导致的状态不一致

    现象:点击了按钮,但预期的弹窗没出现,或者列表没有刷新。

    排查思路

    1. 等待具体的副作用,而非盲目等待时间。不要用sleep。点击按钮后,等待一个具体的元素出现,或者一个特定的网络请求完成。
      # 错误示范 page.get_by_role("button", name="加载更多").click() time.sleep(2) # 不可靠! # 正确示范 page.get_by_role("button", name="加载更多").click() # 等待新项目出现在列表中 expect(page.locator(".list-item").nth(5)).to_be_visible() # 或者等待加载数据的API请求完成 with page.expect_response("**/api/load-more*"): page.get_by_role("button", name="加载更多").click()
    2. 使用Playwright Trace:这是最强大的调试工具。在测试运行配置中启用Trace,它会在测试运行(特别是失败时)记录下每一步的详细快照。
      • 在Pytest中,可以通过命令行参数--tracing=on--tracing=retain-on-failure开启。
      • 也可以在代码中控制:
        context.tracing.start(screenshots=True, snapshots=True, sources=True) # ... 运行测试 ... context.tracing.stop(path = “trace.zip”)
      测试失败后,使用命令playwright show-trace trace.zip打开Trace Viewer。你可以像看视频一样回放测试的每一步,查看当时的DOM状态、网络请求、控制台日志,精准定位问题发生的那一刻。

    6.3 测试在CI/CD上失败,本地却成功

    现象:脚本在本地开发机器上跑得好好的,一上Jenkins/GitHub Actions就挂。

    排查思路

    1. 环境差异:这是首要怀疑对象。CI环境通常是Linux无头服务器,屏幕分辨率、字体、甚至时区都可能不同。
      • 解决方案:在browser.new_context()browser_context_argsfixture中,明确指定视口大小、用户代理等。
        context = browser.new_context( viewport={‘width’: 1920, ‘height’: 1080}, user_agent=‘Mozilla/5.0 ...’, locale=‘zh-CN’ # 设置语言区域 )
    2. 资源加载超时:CI服务器网络可能较慢,或者测试环境服务器响应慢。
      • 解决方案:适当增加全局超时时间,但更重要的是优化等待策略,使用wait_for_selector代替固定的goto超时。
        # 在pytest-playwright中,可以通过fixture设置 @pytest.fixture(scope=“session”) def browser_context_args(browser_context_args): return {**browser_context_args, “base_url”: “https://test-env.example.com”} # 然后在测试中使用相对路径,并配置更长的默认超时(谨慎使用) page.set_default_timeout(60000) # 60秒
    3. 依赖服务不稳定:测试依赖的第三方API或测试环境本身不稳定。
      • 解决方案:这不是Playwright能解决的。需要对测试环境进行治理,或者编写更“宽容”的测试(例如,对于非核心的第三方组件,可以mock掉)。

    6.4 性能与稳定性优化建议

    1. 复用Browser Context:启动浏览器开销很大。在测试套件级别(scope=“session”)启动一个Browser,然后为每个测试用例创建一个新的Context(scope=“function”),这样既能隔离测试,又能获得最佳性能。
    2. 并行执行:Pytest支持-n参数并行运行测试。Playwright可以很好地支持并行,因为每个测试运行在自己的Browser Context里,是天然隔离的。确保你的测试是独立的,不共享状态。
    3. 失败重试:对于偶尔因网络抖动导致的失败,可以配置重试机制。在Pytest中,可以使用pytest-rerunfailures插件,或者直接在Playwright Test配置中设置重试。
    4. 定期清理:CI服务器上可能会积累大量的浏览器二进制文件和Trace文件。编写清理脚本,定期清理旧的playwright缓存和测试产出物。

    最后,记住UI自动化测试不是银弹。它最适合覆盖核心的、稳定的用户旅程(Happy Path)。对于极度动态的、视觉化的、或探索性的测试,可能需要结合API测试、单元测试和手动测试。Playwright是一个强大的工具,它能将你从繁琐、不稳定的传统Web自动化中解放出来,让你更专注于设计有价值的测试用例和构建可靠的交付流水线。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/20 21:23:28

xray被动扫描器实战指南:从安装配置到精准漏洞挖掘

1. 项目概述&#xff1a;为什么我们需要一个专业的被动扫描器&#xff1f;在安全测试的日常工作中&#xff0c;无论是渗透测试工程师、安全研究员还是负责业务安全的开发人员&#xff0c;都绕不开一个核心环节&#xff1a;漏洞发现。传统的手工测试虽然精准&#xff0c;但效率低…

作者头像 李华
网站建设 2026/6/20 21:22:13

Grok 4.20四Agent模式:提示词工程驱动的显式分片推理

1. 这不是“开会”&#xff0c;是“交作业”&#xff1a;Grok 4.20 四 Agent 模式的真实运行逻辑 你点开 Grok 4.20 的新界面&#xff0c;看到 Harper、Benjamin、Lucas、还有那个始终居中调度的 Grok 本体——四个头像排开&#xff0c;像一支刚领完任务的特种小队。宣传材料里…

作者头像 李华
网站建设 2026/6/20 21:18:52

WSL+Python+pipx搭建本地AI智能体:Hermes Agent实战指南

1. 项目概述&#xff1a;这不是一个“玩具”&#xff0c;而是一套可落地的本地化智能体工作流你有没有过这种体验&#xff1a;在浏览器里打开某个AI工具&#xff0c;输入问题&#xff0c;等几秒&#xff0c;得到答案&#xff0c;然后关掉页面——整个过程像在便利店买瓶水&…

作者头像 李华
网站建设 2026/6/20 21:18:23

Python国密SM4算法实战:pysm4库原理、应用与安全实践

1. 项目概述&#xff1a;为什么我们需要关注pysm4&#xff1f;如果你在金融、政务或者对数据安全有高要求的行业里摸爬滚打过&#xff0c;那么“国密算法”这个词对你来说一定不陌生。它不是某个新潮的编程框架&#xff0c;而是一套由国家密码管理局发布的商用密码算法标准体系…

作者头像 李华