Playwright是微软官方推出的浏览器自动化库,支持Chromium、Firefox和WebKit等主流浏览器引擎,在C#项目中可以借助它完成网页自动操作、数据采集、界面回归测试等任务。与传统的Selenium相比,Playwright的API设计更加简洁,执行速度更快,在处理弹窗、多页面、网络拦截等场景时也更为可靠。本文将从环境准备、基础初始化、常见操作、注意事项和完整示例等方面,详细介绍在C#中如何使用Playwright实现浏览器自动化。

环境准备与依赖安装
在开始编写自动化代码之前,需要先为C#项目安装Playwright的NuGet包。打开Visual Studio的“管理解决方案的NuGet程序包”窗口,搜索Microsoft.Playwright并安装最新稳定版即可。该包会引入Playwright的核心API以及对应的浏览器驱动管理工具。
安装完成NuGet包后,还需要执行一次浏览器驱动安装操作,确保本地存在可用的浏览器环境。通常情况下,可以在程序包管理器控制台中依次运行以下两行命令来完成驱动组件的安装和浏览器二进制文件的下载:
// 在程序包管理器控制台执行以下命令 // 第一行:安装Playwright的命令行工具 dotnet tool install --global Microsoft.Playwright.CLI // 第二行:下载并安装Chromium等浏览器驱动文件 playwright install
如果只需要某一种浏览器,可以在playwright install后面附加浏览器名称,例如playwright install chromium。安装过程可能需要一些时间,取决于网络状况和系统环境。安装完毕后,项目就可以正常引用Playwright的类型和方法了。
基础初始化与页面导航
使用Playwright的第一步是创建Playwright实例,然后通过该实例启动指定的浏览器。启动浏览器时可以选择有头模式或无头模式,无头模式不显示浏览器窗口,适合在服务器或CI环境中运行。创建浏览器对象后,需要再创建一个页面对象,这个页面对象代表浏览器中的一个标签页,后续的所有操作都会基于它执行。
下面是一个最基础的导航示例,该示例启动Chromium浏览器,打开一个目标网页,等待网络空闲后输出页面标题。代码中使用了异步编程模式,这是Playwright的推荐用法,能够避免阻塞UI线程。
using Microsoft.Playwright;
using System;
using System.Threading.Tasks;
class Program
{
static async Task Main(string[] args)
{
// 初始化Playwright实例
using var playwright = await Playwright.CreateAsync();
// 启动Chromium浏览器,设置为无头模式
await using var browser = await playwright.Chromium.LaunchAsync(
new BrowserTypeLaunchOptions
{
Headless = true
});
// 新建一个页面对象
var page = await browser.NewPageAsync();
// 导航到目标网址
await page.GotoAsync("https://ipipp.com");
// 等待页面网络请求全部完成
await page.WaitForLoadStateAsync(LoadState.NetworkIdle);
// 输出页面标题
Console.WriteLine("页面标题:" + await page.TitleAsync());
// 关闭浏览器
await browser.CloseAsync();
}
}
在上面的代码中,Playwright.CreateAsync()用于初始化整个自动化环境,LaunchAsync负责启动浏览器进程。创建页面后,GotoAsync会将页面导航到指定URL,WaitForLoadStateAsync则确保页面中的关键资源已经加载完成。这种基础流程是后续所有自动化操作的前提。
常见自动化操作实现
元素定位与点击
Playwright提供了非常丰富的元素定位方式,包括CSS选择器、文本内容、属性值等。定位到元素后,可以直接调用点击、填写等操作方法。下面列举了几种常用的定位与点击方式,可以看到代码非常简洁。
// 通过CSS选择器定位按钮并点击
await page.ClickAsync("button.submit-btn");
// 通过按钮文本内容定位并点击
await page.ClickAsync("text=提交");
// 通过元素属性定位并点击
await page.ClickAsync("[data-testid='login-button']");
在定位元素时,建议优先使用稳定的选择器,例如带有id或data-testid属性的元素。这些属性通常不会因为页面样式调整而改变,能够降低自动化脚本的维护成本。如果页面中存在多个匹配的元素,Playwright会默认选择第一个,如果希望选择特定索引的元素,可以使用nth语法,例如button.submit-btn >> nth=1。
表单填写与输入
表单输入是自动化操作中非常常见的场景。Playwright的FillAsync方法可以直接为输入框设置值,SelectOptionAsync方法可以操作下拉选择框。下面的示例演示了如何填写用户名、密码以及选择城市。
// 填写用户名输入框
await page.FillAsync("#username", "test_user");
// 填写密码输入框
await page.FillAsync("#password", "test_password123");
// 根据选项文本选择下拉框值
await page.SelectOptionAsync("select#city", "北京");
需要注意,FillAsync会先清空输入框中的已有内容,再填入新值。如果需要在原有内容的基础上追加字符,可以结合PressSequentiallyAsync方法来模拟键盘逐字输入。对于上传文件类型的输入框,Playwright也提供了SetInputFilesAsync方法来设置本地文件路径。
数据提取
从页面中提取文本、属性或列表数据是数据抓取类任务的核心环节。Playwright提供了多个方法来读取页面信息,它们都返回异步任务,需要使用await获取结果。下面的示例展示了如何获取单元素文本、属性值以及多个元素的文本内容。
// 提取元素的文本内容
var content = await page.TextContentAsync(".article-title");
Console.WriteLine("文章标题:" + content);
// 提取元素的属性值
var link = await page.GetAttributeAsync("a.detail-link", "href");
Console.WriteLine("文章链接:" + link);
// 提取多个元素的内容
var items = await page.QuerySelectorAllAsync(".list-item");
foreach (var item in items)
{
var text = await item.TextContentAsync();
Console.WriteLine("列表项内容:" + text);
}
当页面是动态渲染时,提取数据前可能需要先等待目标元素出现。Playwright的WaitForSelectorAsync方法可以指定元素等待超时时间,如果在超时时间内元素仍不可见,则会抛出异常。合理地使用等待方法能够有效避免因网络延迟导致的元素未加载完成问题。
注意事项
在实际使用Playwright的过程中,有几个细节需要特别留意。首先,如果自动化任务不需要可视化界面,建议将Headless设置为true,这样既节省系统资源,也便于在无桌面的服务器环境中运行。其次,在操作元素之前最好先调用WaitForSelectorAsync等待元素可见,尤其是对于异步加载的内容,否则可能会出现找不到元素的异常。
当自动化脚本需要处理本地测试环境时,可以直接使用回环地址或局域网地址,例如127.0.0.1或192.168.0.1,不需要做额外处理。另外,在代码中描述HTML标签名称时,需要按照HTML转义规则书写,例如在描述输入框时应写为<input>,而不能直接写<input>的原始形式,这样会导致页面解析出错。
还有一点是浏览器关闭的问题。在不需要继续使用浏览器时,应当调用CloseAsync方法释放资源。使用await using声明的浏览器对象会在作用域结束时自动释放,但在显式需要控制生命周期时,手动调用关闭方法依然是更稳妥的做法。
完整示例:自动登录演示
为了将前面介绍的知识点串联起来,这里给出一个完整的自动登录流程示例。该示例模拟用户打开登录页面,填写用户名和密码,点击登录按钮,并等待跳转至首页。为了便于观察执行过程,浏览器窗口被设置为非无头模式,实际运行时可以将其改为Headless = true。
using Microsoft.Playwright;
using System;
using System.Threading.Tasks;
class LoginDemo
{
static async Task Main(string[] args)
{
using var playwright = await Playwright.CreateAsync();
await using var browser = await playwright.Chromium.LaunchAsync(
new BrowserTypeLaunchOptions
{
Headless = false // 设置为false可以看到浏览器操作过程
});
var page = await browser.NewPageAsync();
// 打开登录页面
await page.GotoAsync("https://ipipp.com/login");
// 等待用户名输入框出现在页面中
await page.WaitForSelectorAsync("#username");
// 填写登录信息
await page.FillAsync("#username", "demo_user");
await page.FillAsync("#password", "demo_pass");
// 点击登录按钮
await page.ClickAsync("button#login-btn");
// 等待URL跳转到包含/home的地址
await page.WaitForURLAsync("**/home");
Console.WriteLine("登录成功,当前页面地址:" + page.Url);
// 关闭浏览器
await browser.CloseAsync();
}
}
在这个完整示例中,WaitForURLAsync是一个非常有用的等待方法,它会持续监听页面URL的变化,直到URL与给定的模式匹配。模式中的**表示通配符,可以匹配任意路径前缀。通过这种方式,可以相当可靠地判断登录是否成功,而无需额外检查特定元素。
以上示例只是一个起点,Playwright还支持截图、PDF生成、网络请求拦截、多标签页管理、断言库集成等高级功能。在编写自动化脚本时,建议将常用的操作封装成独立的方法,提高代码的复用性和可读性。同时,合理使用等待策略和选择器优先级,可以显著提升自动化任务的稳定性。
总体而言,Playwright为C#开发者提供了一套现代、高效的浏览器自动化方案。通过本文的介绍,相信你已经掌握了环境搭建、基础导航、元素操作以及完整流程的编写方法。在实际项目中,可以结合自己的业务场景灵活运用这些知识点,实现更复杂的自动化需求。
C#Playwright浏览器自动化自动化测试修改时间:2026-07-09 16:18:30