C# Playwright 自动化:网页行为模拟与 AI 对话数据提取
本文包含AI辅助创作内容
背景
不少 AI 平台的 API 接口并不支持联网搜索功能,如果需要获取实时信息,通常要自行接入第三方搜索 API,再将搜索结果拼接到 Prompt 中回传给模型——实现成本高,且效果参差不齐。然而,这些 AI 的网页端往往已经内置了智能搜索能力,可以直接获取实时信息并生成回答。
既然网页端已经具备完整能力,何不直接模拟浏览器操作?Playwright 是微软开源的浏览器自动化工具,支持 Chromium、Firefox、WebKit 等多种浏览器引擎,提供 C#、Java、JavaScript、Python 等多语言 SDK,可以模拟用户在浏览器中的各种操作——点击按钮、输入文本、下载文件等。
本文以 C# 为例,演示如何使用 Playwright 自动化操作百度 AI 对话页面,绕过 API 限制,直接利用网页端的智能搜索能力,实现提问并导出 Markdown 格式回答的完整流程。
流程概览
1. 环境准备
在 C# 项目中安装 Playwright 依赖:
dotnet add package Microsoft.Playwright
安装完成后,还需安装浏览器引擎:
Microsoft.Playwright.Program.Main(["install", "chromium"]);
2. 创建浏览器实例
使用持久化上下文(Persistent Context)启动 Chromium,这样可以复用已有的登录状态,避免每次都需要重新登录(也可以每次都使用新目录,实现无痕模式):
// 创建 Playwright 实例
using var playwright = await Playwright.CreateAsync();
// 使用持久化上下文启动 Chromium
await using var browser = await playwright.Chromium.LaunchPersistentContextAsync(
userDataDir,
new() { Headless = true });
💡 userDataDir 为浏览器用户数据目录路径,登录状态会保存在该目录中。设置 Headless = true 表示无头模式运行,不显示浏览器窗口;如需调试可设为 false。
3. 导航并输入提问
新建页面后,导航到百度 AI 对话页面,等待加载完成,然后在输入框中输入问题:
// 新建页面
var page = await browser.NewPageAsync();
// 导航到百度 AI 对话页面
await page.GotoAsync("https://chat.baidu.com/");
// 等待页面加载完成
await page.WaitForLoadStateAsync();
// 点击输入框并输入提问内容
await page.Locator("#chat-textarea").ClickAsync();
await page.Keyboard.TypeAsync("吴彦祖有我帅吗");
4. 提交问题并等待回复
点击提交按钮发送问题,等待 AI 回复完成:
// 点击 AI 提交按钮发送问题
await page.Locator("#ci-submit-button-ai").ClickAsync();
// 等待1秒让 AI 开始生成回复
await Task.Delay(1000);
// 等待提交按钮重新可见(AI 回复完成后按钮恢复可用状态)
await page.Locator("#ci-submit-button-ai").WaitForAsync(
new() { State = WaitForSelectorState.Visible });
💡 提交按钮在 AI 回复期间会变为不可见状态,回复完成后恢复可见。因此通过等待按钮重新可见来判断回复已完成,比固定延时更可靠。
5. 导出 Markdown 格式的回答
点击输出区域的菜单按钮,选择 Markdown 格式导出,并读取下载的文件内容:
// 点击输出区域的菜单按钮
await page.GetByTestId("menu-btn-out").ClickAsync();
// 点击"Markdown"选项并等待下载完成
var download = await page.RunAndWaitForDownloadAsync(async () =>
{
await page.Locator("div[class='cos-tooltip-content'] span:has-text('Markdown')")
.ClickAsync();
});
// 读取下载的 Markdown 文件内容
using var stream = await download.CreateReadStreamAsync();
using var reader = new StreamReader(stream);
string content = await reader.ReadToEndAsync();
Console.WriteLine(content);
6. Stealth 模式:规避自动化检测
部分网站会检测浏览器是否由自动化工具控制,导致请求被拦截或功能受限。通过 Stealth 扩展可以降低被识别的风险:
dotnet add package Soenneker.Playwrights.Extensions.Stealth
只需在创建浏览器后添加一行配置即可启用:
await browser.ApplyStealth(new StealthContextOptions()
{
NormalizeDocumentHeaders = true,
InjectClientHintHeaders = true
});
💡 NormalizeDocumentHeaders 会标准化浏览器请求头,InjectClientHintHeaders 会注入客户端提示信息,两者配合使用可有效降低被检测概率。
完整代码
using Microsoft.Playwright;
var userDataDir = "你的用户数据目录路径";
using var playwright = await Playwright.CreateAsync();
await using var browser = await playwright.Chromium.LaunchPersistentContextAsync(
userDataDir,
new() { Headless = true });
await browser.ApplyStealth(new StealthContextOptions()
{
NormalizeDocumentHeaders = true,
InjectClientHintHeaders = true
});
var page = await browser.NewPageAsync();
await page.GotoAsync("https://chat.baidu.com/");
await page.WaitForLoadStateAsync();
await page.Locator("#chat-textarea").ClickAsync();
await page.Keyboard.TypeAsync("吴彦祖有我帅吗");
await page.Locator("#ci-submit-button-ai").ClickAsync();
await Task.Delay(1000);
await page.Locator("#ci-submit-button-ai").WaitForAsync(
new() { State = WaitForSelectorState.Visible });
await page.GetByTestId("menu-btn-out").ClickAsync();
var download = await page.RunAndWaitForDownloadAsync(async () =>
{
await page.Locator("div[class='cos-tooltip-content'] span:has-text('Markdown')")
.ClickAsync();
});
using var stream = await download.CreateReadStreamAsync();
using var reader = new StreamReader(stream);
string content = await reader.ReadToEndAsync();
Console.WriteLine(content);
小结
本文通过 Playwright 的 Chromium 无头浏览器,实现了在百度 AI 对话页面自动提问并导出 Markdown 格式回答的完整流程。核心要点:
RunAndWaitForDownloadAsync 读取内容
此方案不仅适用于百度 AI 对话,也可扩展到其他需要自动化操作网页并获取结果的场景,如批量数据采集、定时任务执行等。

请先 登录后发表评论 ~