目录

  1. 前提条件

  2. 添加按钮到WinForms窗体

  3. 实现按钮点击事件以获取HTML

  4. 完整示例代码

  5. 注意事项

  6. 常见问题与解决方法

  7. 参考资料

  8. 总结


1. 前提条件

在开始之前,请确保已经完成以下准备工作:

  • 已集成WebView2控件:确保WebView2控件已成功添加到WinForms项目中。

  • 安装WebView2运行时:确保系统中安装了WebView2运行时。

  • 项目目标框架:建议使用 .NET Framework 4.6.2 及以上,或 .NET Core/5+/6+。


2. 添加按钮到WinForms窗体

为了让用户在点击按钮后获取当前网页的HTML内容,需要在WinForms窗体中添加一个按钮控件。

步骤:

  1. 打开设计器视图

    • 在解决方案资源管理器中,双击WinForms窗体(例如 Form1.cs),进入设计器视图。

  2. 添加按钮控件

    • 从工具箱中拖放一个 Button 控件到窗体上。

    • 设置按钮的属性:

      • NamebtnGetHtml

      • Text获取HTML

  3. 布局调整

    • 将按钮放置在适当的位置,例如窗体的顶部或底部。

    • 可以调整按钮的大小和位置,以适应布局需求。


3. 实现按钮点击事件以获取HTML

在按钮的点击事件中,执行JavaScript代码以获取当前网页的HTML内容,并将其显示在文本框中或进行其他处理。

步骤:

  1. 双击按钮

    • 在设计器视图中,双击 btnGetHtml 按钮,Visual Studio 会自动生成点击事件处理程序并跳转到代码视图。

  2. 编写点击事件处理代码

    在生成的 btnGetHtml_Click 方法中,添加代码以执行JavaScript获取HTML,并处理返回的结果。

示例代码:

using System;
using System.Text.Json;
using System.Threading.Tasks;
using System.Windows.Forms;
using Microsoft.Web.WebView2.WinForms;
using Microsoft.Web.WebView2.Core;

namespace WebView2GetHtmlExample
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            InitializeAsync();
        }

        private async void InitializeAsync()
        {
            try
            {
                // 初始化 WebView2
                await webView21.EnsureCoreWebView2Async(null);

                // 导航到目标网页
                webView21.CoreWebView2.Navigate("https://www.example.com"); // 替换为目标URL
            }
            catch (Exception ex)
            {
                MessageBox.Show($"WebView2 初始化失败: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private async void btnGetHtml_Click(object sender, EventArgs e)
        {
            try
            {
                // 确保WebView2已初始化
                if (webView21.CoreWebView2 == null)
                {
                    MessageBox.Show("WebView2尚未初始化。请稍候再试。", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    return;
                }

                // 执行JavaScript获取HTML
                string script = "document.documentElement.outerHTML;";
                string result = await webView21.CoreWebView2.ExecuteScriptAsync(script);

                // 解析返回的JSON字符串
                string htmlContent = JsonSerializer.Deserialize<string>(result);

                // 显示HTML内容在文本框中
                textBoxHtml.Text = htmlContent;

                // 或者保存到文件
                // System.IO.File.WriteAllText("page.html", htmlContent);

                MessageBox.Show("成功获取HTML内容!", "成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            catch (Exception ex)
            {
                MessageBox.Show($"获取HTML内容失败: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
    }
}

代码解释:

  1. 初始化 WebView2

    await webView21.EnsureCoreWebView2Async(null);
    webView21.CoreWebView2.Navigate("https://www.example.com");
    

    确保WebView2控件已初始化,并导航到目标网页。

  2. 按钮点击事件处理

    private async void btnGetHtml_Click(object sender, EventArgs e)
    {
        try
        {
            // 确保WebView2已初始化
            if (webView21.CoreWebView2 == null)
            {
                MessageBox.Show("WebView2尚未初始化。请稍候再试。", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }
    
            // 执行JavaScript获取HTML
            string script = "document.documentElement.outerHTML;";
            string result = await webView21.CoreWebView2.ExecuteScriptAsync(script);
    
            // 解析返回的JSON字符串
            string htmlContent = JsonSerializer.Deserialize<string>(result);
    
            // 显示HTML内容在文本框中
            textBoxHtml.Text = htmlContent;
    
            // 或者保存到文件
            // System.IO.File.WriteAllText("page.html", htmlContent);
    
            MessageBox.Show("成功获取HTML内容!", "成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }
        catch (Exception ex)
        {
            MessageBox.Show($"获取HTML内容失败: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
    }
    
    • 检查WebView2是否初始化:确保在执行脚本前,WebView2控件已正确初始化。

    • 执行JavaScript:使用 ExecuteScriptAsync 方法执行JavaScript代码,获取整个网页的HTML内容。

    • 解析结果ExecuteScriptAsync 返回的是一个JSON字符串,需要使用 JsonSerializer.Deserialize<string> 将其转换为C#字符串。

    • 显示或处理HTML:将获取到的HTML内容显示在文本框 textBoxHtml 中,或根据需要保存到文件。


4. 完整示例代码

以下是一个完整的WinForms项目示例,展示如何在点击按钮后获取WebView2控件中当前页面的HTML内容并显示在文本框中。

步骤1:创建新的WinForms项目

  1. 打开Visual Studio

  2. 创建新项目

    • 选择 “Windows Forms 应用程序 (.NET Framework)”“.NET Core”,点击 “下一步”

    • 配置项目名称(例如 WebView2GetHtmlExample)和位置,点击 “创建”

步骤2:安装WebView2 NuGet包

  1. 打开NuGet包管理器

    • 右键点击项目,选择 “管理NuGet程序包…”

  2. 搜索并安装Microsoft.Web.WebView2

    • “浏览” 标签下,搜索 Microsoft.Web.WebView2

    • 选择 Microsoft.Web.WebView2 包(由Microsoft发布),点击 “安装”

    • 接受许可协议,等待安装完成。

步骤3:设计界面

  1. 打开设计器视图

    • 在解决方案资源管理器中,双击 Form1.cs,进入设计器视图。

  2. 添加WebView2控件

    • 如果WebView2控件已显示在工具箱中,直接拖放到窗体上。

    • 否则,手动添加:

      • 右键点击 “工具箱”,选择 “选择项…”

      • “.NET Framework 组件” 选项卡中,找到 Microsoft.Web.WebView2.WinForms.WebView2

      • 勾选该控件,点击 “确定”

    • 将WebView2控件调整为适合窗体的大小。

  3. 添加按钮控件

    • 从工具箱中拖放一个 Button 控件到窗体上。

    • 设置按钮的属性:

      • NamebtnGetHtml

      • Text获取HTML

    • 将按钮放置在WebView2控件的下方或适当位置。

  4. 添加文本框控件

    • 从工具箱中拖放一个 TextBox 控件到窗体上。

    • 设置文本框的属性:

      • NametextBoxHtml

      • MultilineTrue

      • ScrollBarsVertical

      • DockBottom 或根据需要调整位置。

    • 调整文本框的大小以适应显示HTML内容。

步骤4:编写代码

Form1.cs

using System;
using System.Text.Json;
using System.Windows.Forms;
using Microsoft.Web.WebView2.WinForms;
using Microsoft.Web.WebView2.Core;

namespace WebView2GetHtmlExample
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            InitializeAsync();
        }

        private async void InitializeAsync()
        {
            try
            {
                // 初始化 WebView2
                await webView21.EnsureCoreWebView2Async(null);

                // 导航到目标网页
                webView21.CoreWebView2.Navigate("https://www.example.com"); // 替换为目标URL
            }
            catch (Exception ex)
            {
                MessageBox.Show($"WebView2 初始化失败: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private async void btnGetHtml_Click(object sender, EventArgs e)
        {
            try
            {
                // 确保WebView2已初始化
                if (webView21.CoreWebView2 == null)
                {
                    MessageBox.Show("WebView2尚未初始化。请稍候再试。", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    return;
                }

                // 执行JavaScript获取HTML
                string script = "document.documentElement.outerHTML;";
                string result = await webView21.CoreWebView2.ExecuteScriptAsync(script);

                // 解析返回的JSON字符串
                string htmlContent = JsonSerializer.Deserialize<string>(result);

                // 显示HTML内容在文本框中
                textBoxHtml.Text = htmlContent;

                // 或者保存到文件
                // System.IO.File.WriteAllText("page.html", htmlContent);

                MessageBox.Show("成功获取HTML内容!", "成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            catch (Exception ex)
            {
                MessageBox.Show($"获取HTML内容失败: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
    }
}

Form1.Designer.cs

确保 Form1.Designer.cs 文件包含WebView2控件、按钮和文本框的初始化代码:

namespace WebView2GetHtmlExample
{
    partial class Form1
    {
        private Microsoft.Web.WebView2.WinForms.WebView2 webView21;
        private System.Windows.Forms.Button btnGetHtml;
        private System.Windows.Forms.TextBox textBoxHtml;

        /// <summary>
        /// 设计器支持所需的方法 - 不要修改
        /// 使用代码编辑器修改此方法的内容。
        /// </summary>
        private void InitializeComponent()
        {
            this.webView21 = new Microsoft.Web.WebView2.WinForms.WebView2();
            this.btnGetHtml = new System.Windows.Forms.Button();
            this.textBoxHtml = new System.Windows.Forms.TextBox();
            ((System.ComponentModel.ISupportInitialize)(this.webView21)).BeginInit();
            this.SuspendLayout();
            // 
            // webView21
            // 
            this.webView21.CreationProperties = null;
            this.webView21.DefaultBackgroundColor = System.Drawing.Color.White;
            this.webView21.Location = new System.Drawing.Point(12, 12);
            this.webView21.Name = "webView21";
            this.webView21.Size = new System.Drawing.Size(776, 300);
            this.webView21.TabIndex = 0;
            this.webView21.ZoomFactor = 1D;
            // 
            // btnGetHtml
            // 
            this.btnGetHtml.Location = new System.Drawing.Point(12, 318);
            this.btnGetHtml.Name = "btnGetHtml";
            this.btnGetHtml.Size = new System.Drawing.Size(100, 30);
            this.btnGetHtml.TabIndex = 1;
            this.btnGetHtml.Text = "获取HTML";
            this.btnGetHtml.UseVisualStyleBackColor = true;
            this.btnGetHtml.Click += new System.EventHandler(this.btnGetHtml_Click);
            // 
            // textBoxHtml
            // 
            this.textBoxHtml.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
                                                                            | System.Windows.Forms.AnchorStyles.Left) 
                                                                            | System.Windows.Forms.AnchorStyles.Right)));
            this.textBoxHtml.Location = new System.Drawing.Point(12, 354);
            this.textBoxHtml.Multiline = true;
            this.textBoxHtml.Name = "textBoxHtml";
            this.textBoxHtml.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
            this.textBoxHtml.Size = new System.Drawing.Size(776, 84);
            this.textBoxHtml.TabIndex = 2;
            // 
            // Form1
            // 
            this.ClientSize = new System.Drawing.Size(800, 450);
            this.Controls.Add(this.textBoxHtml);
            this.Controls.Add(this.btnGetHtml);
            this.Controls.Add(this.webView21);
            this.Name = "Form1";
            this.Text = "WebView2 获取HTML示例";
            ((System.ComponentModel.ISupportInitialize)(this.webView21)).EndInit();
            this.ResumeLayout(false);
            this.PerformLayout();
        }
    }
}

运行应用程序

  1. 按 F5 运行应用程序。

  2. 观察结果

    • WebView2控件会导航到指定的URL(例如 https://www.example.com)。

    • 加载完成后,点击 “获取HTML” 按钮。

    • 网页的HTML内容将显示在下方的文本框 textBoxHtml 中。

    • 弹出消息框提示成功获取HTML内容。


5. 注意事项

  1. 异步编程

    • ExecuteScriptAsync 方法是异步的,确保使用 asyncawait 关键字,以避免阻塞UI线程。

  2. JSON解析

    • ExecuteScriptAsync 返回的是一个JSON字符串,通常是双引号包围的字符串。使用 JsonSerializer.Deserialize<string> 或其他JSON解析方法将其转换为C#字符串。

  3. 错误处理

    • 添加适当的错误处理机制,捕获和处理可能出现的异常,确保应用程序的稳定性。

  4. UI更新

    • 在跨线程操作UI元素时,确保在UI线程上进行操作。虽然在WinForms中通常不需要额外处理,因为事件处理程序默认在UI线程上执行。

  5. 性能优化

    • 避免频繁执行大量的JavaScript代码,合理安排获取HTML的时机,以提高应用程序的性能。

  6. 安全性

    • 确保仅在受信任的网页上执行JavaScript代码,避免潜在的安全风险。


6. 常见问题与解决方法

问题1:按钮点击后没有反应,HTML内容未显示

可能原因

  • WebView2控件未正确初始化。

  • 点击事件未正确绑定。

  • JavaScript执行出错。

解决方法

  1. 检查WebView2初始化

    • 确保 InitializeAsync 方法已正确执行,并且WebView2控件已导航到目标网页。

    • 可以在 NavigationCompleted 事件中添加日志,确认导航是否成功。

  2. 检查按钮事件绑定

    • 确认 btnGetHtml_Click 方法已正确绑定到按钮的 Click 事件。

    • Form1.Designer.cs 中确认:

      this.btnGetHtml.Click += new System.EventHandler(this.btnGetHtml_Click);
      
  3. 检查JavaScript执行

    • 在开发者工具中(通过WebView2的DevTools),检查是否有JavaScript错误。

    • 确保脚本 document.documentElement.outerHTML; 能正确执行。

问题2:获取的HTML内容为空或不完整

可能原因

  • 网页尚未完全加载时执行脚本。

  • 网页动态内容未被完全渲染。

解决方法

  1. 确保页面完全加载

    • 使用 NavigationCompleted 事件,确保在导航完成后再执行脚本。

  2. 等待动态内容加载

    • 如果网页使用了AJAX或其他动态加载技术,可能需要等待一段时间再获取HTML。

    • 可以在点击按钮时,执行脚本后等待一段时间:

      await Task.Delay(1000); // 等待1秒
      
  3. 使用显式等待

    • 检查特定元素是否存在,确保页面加载完成:

      var success = await webView21.CoreWebView2.ExecuteScriptAsync("document.readyState").ContinueWith(t => 
          JsonSerializer.Deserialize<string>(t.Result) == ""complete"");
      if (success)
      {
          // 执行获取HTML的脚本
      }
      

问题3:在文本框中显示的HTML包含转义字符或额外的引号

可能原因

  • ExecuteScriptAsync 返回的是JSON字符串,包含转义字符和引号。

解决方法

  • 使用 JsonSerializer.Deserialize<string> 正确解析返回的结果,如示例代码所示。

    string htmlContent = JsonSerializer.Deserialize<string>(result);
    

问题4:WebView2控件报错“未能解析类型 Microsoft.Web.WebView2.WinForms.WebView2”

解决方法

  1. 确认NuGet包已正确安装

    • 在解决方案资源管理器中,展开 “依赖项” > “NuGet”,确保 Microsoft.Web.WebView2 包已列出。

  2. 检查项目目标框架

    • 在项目属性中,确保目标框架为 .NET Framework 4.6.2 及以上,或 .NET Core/5+/6+。

  3. 重启Visual Studio

    • 有时,安装NuGet包后需要重启Visual Studio才能识别新引用。

  4. 清理并重建解决方案

    • 选择 “生成” > “清理解決方案”,然后 “生成” > “生成解决方案”

  5. 手动添加引用

    • 在设计器视图中,确保WebView2控件已添加到工具箱并拖放到窗体上。


7. 参考资料


8. 总结

在WinForms应用程序中使用WebView2控件,并在用户点击按钮后获取当前网页的HTML内容,是实现网页数据抓取、内容分析或自动化测试等功能的有效方法。通过以下关键步骤,可以轻松地实现这一功能:

  1. 正确集成WebView2控件

    • 确保已安装WebView2运行时。

    • 通过NuGet包管理器安装 Microsoft.Web.WebView2 包,并将控件添加到窗体上。

  2. 设计用户界面

    • 添加WebView2控件、按钮和文本框,以便用户操作和显示HTML内容。

  3. 实现功能逻辑

    • 在按钮点击事件中,使用 ExecuteScriptAsync 方法执行JavaScript代码获取HTML,并将结果显示或处理。

  4. 处理常见问题

    • 确保WebView2控件已正确初始化。

    • 使用异步编程模式,确保不会阻塞UI线程。

    • 正确解析JSON格式的返回值。