惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Webroot Blog
Webroot Blog
U
Unit 42
A
About on SuperTechFans
宝玉的分享
宝玉的分享
月光博客
月光博客
C
CERT Recently Published Vulnerability Notes
P
Privacy International News Feed
Microsoft Security Blog
Microsoft Security Blog
G
Google Developers Blog
P
Privacy & Cybersecurity Law Blog
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
S
Securelist
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Spread Privacy
Spread Privacy
L
Lohrmann on Cybersecurity
Apple Machine Learning Research
Apple Machine Learning Research
K
Kaspersky official blog
Hugging Face - Blog
Hugging Face - Blog
B
Blog
I
Intezer
Last Week in AI
Last Week in AI
T
Threat Research - Cisco Blogs
V
V2EX
L
LangChain Blog
AI
AI
G
GRAHAM CLULEY
T
Tor Project blog
人人都是产品经理
人人都是产品经理
D
Docker
WordPress大学
WordPress大学
Google DeepMind News
Google DeepMind News
I
InfoQ
Y
Y Combinator Blog
C
Comments on: Blog
GbyAI
GbyAI
www.infosecurity-magazine.com
www.infosecurity-magazine.com
酷 壳 – CoolShell
酷 壳 – CoolShell
T
Tailwind CSS Blog
aimingoo的专栏
aimingoo的专栏
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
腾讯CDC
N
News and Events Feed by Topic
MyScale Blog
MyScale Blog
H
Help Net Security
Vercel News
Vercel News
T
Tenable Blog
博客园 - 三生石上(FineUI控件)
爱范儿
爱范儿

博客园 - zhaotianff

一文带你搞懂医疗器械设计开发全生命周期 Windows如何清除本机记录的git用户名和密码 HL7协议详解 医疗行业 GDT 数据格式详解 一文带你搞懂C# 异步编程(async/await)底层原理 不同.NET版本中的WPF新增功能 如何在WPF中使用 Fluent 主题 Windows平台下的各种原生UI框架介绍 C#如何Hook托管函数 WinDbg 用户层调试进阶教程 Windows编程的一些基础理论 推荐一款优秀的Windows经典文件管理器项目-WinFile Windows如何阻止应用程序联网 如何在WPF中捕获窗口外的事件 如何查看Windows进程的启动来源 Visual Studio 2026新解决方案格式slnx详解 我的微软MVP申请通过了 WPF MVVM实战系列教程(八、Prism DialogService, 对话框服务) WPF MVVM实战系列教程(七、Prism模块化) WPF 性能优化实战指南 WPF MVVM实战系列教程(六、Prism区域导航) WPF MVVM实战系列教程(五、Prism中的MVVM) WPF MVVM实战系列教程(四、Prism中的依赖注入) 微软 IDE 新纪元:Visual Studio 2026 初体验 Windows 7无法安装VMWare Tools的解决办法 WPF MVVM实战系列教程(三、创建Bootstrapper/启动器) WPF MVVM实战系列教程(二、使用Visual Studio 创建Prism项目) WPF MVVM实战系列教程(一、Prism框架介绍)
如何在C#中使用Chromium headless(无头模式)浏览器
zhaotianff · 2026-05-20 · via 博客园 - zhaotianff

CEFSharp

在前面的文章中,我介绍过CEFSharp

CEF 全称是Chromium Embedded Framework(Chromium嵌入式框架),是个基于Google Chromium项目的开源Web browser控件,支持Windows, Linux, Mac平台。

CEFSharp就是CEF的C#移植版本。

CEFSharp提供了一个headless(无头模式)版本。

所谓无头模式(Headless Mode),就是浏览器不显示 GUI 界面,后台完整运行渲染引擎与 JS 引擎,适合服务器 / 自动化场景。

如何使用CEFSharp的无头模式

这里提供了一个CefSharp.OffScreen包,基础使用步骤如下:

1、创建一个控制台项目,nuget安装CefSharp.OffScreen包

image

注意:截止最新稳定版 147.0.100,CEFSharp.OffScreen.NETCore包仅支持.NET 6.0-windows版本,后续 不知道会不会支持.NET 6.0以上版本

2、项目属性 → 首选 32 位 / 64 位一致

 

image

3、 设置为 STA 线程

1  class Program
2  {
3      [STAThread]
4      static async Task Main(string[] args)
5      {
6 
7      }
8 }

4、基础使用代码如下

三、绑定核心事件

private static void BindBrowserEvent()
{
    // 页面加载完成
    _browser.LoadCompleted += (s, e) =>
    {
        Console.WriteLine($"页面加载完成:{e.Url} 状态:{e.HttpStatusCode}");
    };

    // 渲染画面回调(每一帧都会触发)
    _browser.Paint += (s, e) =>
    {
        // e.Bitmap 就是当前网页截图
        if (e.Bitmap != null)
        {
            // 只保存一次,避免频繁保存
            static bool saved = false;
            if (!saved)
            {
                e.Bitmap.Save("网页截图.png");
                saved = true;
                Console.WriteLine("截图已保存");
            }
        }
    };

    // JS控制台日志捕获
    _browser.ConsoleMessage += (s, e) =>
    {
        Console.WriteLine($"JS日志:{e.Message}");
    };
}

四、封装加载网页方法

/// <summary>
/// 等待页面加载完成
/// </summary>
private static Task LoadUrlAsync(string url)
{
    var tcs = new TaskCompletionSource<bool>();
    void LoadComplete(object sender, LoadCompletedEventArgs e)
    {
        _browser.LoadCompleted -= LoadComplete;
        tcs.SetResult(true);
    }
    _browser.LoadCompleted += LoadComplete;
    _browser.Load(url);
    return tcs.Task;
}

五、所有常用功能合集

private static async Task RunAllDemoFunc()
{
    // 1. 执行JS获取返回值
    var jsResult = await _browser.EvaluateScriptAsync("document.title");
    if (jsResult.Success)
    {
        Console.WriteLine("网页标题:" + jsResult.Result);
    }

    // 2. 点击页面元素(坐标点击)
    // x,y 网页相对坐标
    _browser.BrowserHost.SendMouseClickEvent(
        x: 120, y: 120, 
        mouseButtonType: MouseButtonType.Left, 
        mouseUp: false, clickCount: 1);

    await Task.Delay(200);
    _browser.BrowserHost.SendMouseClickEvent(
        120, 120, MouseButtonType.Left, true, 1);

    // 3. 输入键盘内容
    _browser.BrowserHost.SendKeyEvent(KeyEventType.KeyDown, (int)Keys.H);
    _browser.BrowserHost.SendKeyEvent(KeyEventType.Char, 'H');
    _browser.BrowserHost.SendKeyEvent(KeyEventType.KeyUp, (int)Keys.H);

    // 4. 网页后退/前进/刷新
    _browser.Back();
    _browser.Forward();
    _browser.Reload();

    // 5. 导出网页为PDF
    var pdfSettings = new PdfPrintSettings
    {
        Landscape = false,
        PrintBackground = true
    };
    await _browser.PrintToPdfAsync("网页导出.pdf", pdfSettings);
    Console.WriteLine("PDF导出完成");

    // 6. 设置Cookie
    var cookieManager = Cef.GetGlobalCookieManager();
    cookieManager.SetCookie("https://baidu.com", new Cookie
    {
        Name = "testCookie",
        Value = "123456",
        Domain = ".baidu.com"
    });

    // 7. 获取当前URL
    Console.WriteLine("当前地址:" + _browser.Address);
}

六、关键注意事项

  1. 必须 STA 线程 控制台 Main 加 [STAThread],否则渲染卡死、无画面
  2. 资源释放 ChromiumWebBrowser 一定要Dispose(),最后Cef.Shutdown()
  3. 无头无窗口 看不到界面,所有交互只能代码模拟
  4. 多线程禁止直接操作 Browser 只能在 CEF 事件线程 / 主线程调用
  5. 截图卡顿 Paint 事件每一帧触发,加标记只保存一次即可
  6. .NET 6/7/8 兼容 优先用 CefSharp.OffScreen 112+ 版本

七、截图示例

[STAThread]
static void ScreenshotDemo()
{
    var settings = new CefSettings { DisableGpu = true };
    Cef.Initialize(settings);

    using var browser = new ChromiumWebBrowser("https://www.qq.com", 1024, 768);
    browser.LoadCompleted += (s, e) =>
    {
        Task.Delay(1000).Wait();
    };

    browser.Paint += (s, e) =>
    {
        e.Bitmap?.Save("QQ截图.jpg");
        Console.WriteLine("截图完成");
    };

    System.Threading.Thread.Sleep(3000);
    browser.Dispose();
    Cef.Shutdown();
}

八、常用 API 速查

  • EvaluateScriptAsync 执行 JS
  • SendMouseClickEvent 模拟点击
  • SendKeyEvent 模拟键盘
  • PrintToPdfAsync 导出 PDF
  • LoadHtml 直接加载本地 HTML
  • ZoomLevel 网页缩放

https://www.cnblogs.com/zhaotianff/p/13528507.html