[Asp.net WebForm] 在Asp.net中使用WebBrowser透過https來截圖網頁

WebBrowser screenshot html on ASP.NET

前言

以往都認為WebBrowser沒辦法在ASP.NET中使用,最近不小心解出來,記錄一下

前置作業

WebBrowser的Navigate方法貌似導向https網頁(自簽憑證SSL)會出錯,我的替代方式改先用WebClient把網頁Html字串抓下來再餵給WebBrowser來轉出圖片

我工作上的專案是.Net 3.5,所以使用WebClient,如果你的工作專案.Net Framework版本是.Net 4.5以上的話,建議改用HttpClient比較好

 

如果你的程式版本是.Net 3.5以下,主機可能要安裝下述hotfix,程式才能支援TLS1.2的通訊協定(WebClient、HttpClient、HttpRequest這些物件遠端呼叫時會用到)

Support for TLS System Default Versions included in the .NET Framework 3.5.1 on Windows 7 SP1 and Server 2008 R2 SP1

 

程式碼實作

先自己寫一個類別 MyWebUtility.cs↓

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
using System.Web;
using System.Windows.Forms;

public class MyWebUtily
{ 
    /// <summary>
    /// 用IE核心來截圖網頁
    /// </summary>
    /// <param name="url">目標網址</param>
    /// <param name="width"></param>
    /// <param name="height"></param>
    /// <param name="gifFilePath">gif檔案路徑</param>
    public static void webBrowser_ScreenShotToGif(string url, string gifFilePath, int width, int height)
    {

        Thread th = new Thread(() =>
        { 
            //略過https驗證錯誤
            ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, error) => { return true; };
             
             //讓 WebClient、HttpClient 走 TLS 1.2 協定
             //.Net 3.5寫法↓
             ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072;
             //.Net 4.5寫法↓
             // ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

            //建立 WebClient
            string htmlContent = "";//網頁回傳html字串
            using (WebClient client = new WebClient())
            {
                client.Encoding = Encoding.UTF8; 
                htmlContent = client.DownloadString(url);

            }



            WebBrowser wb = new WebBrowser()
            {
                ScrollBarsEnabled = false,
                IsWebBrowserContextMenuEnabled = false,
                AllowNavigation = true,
                ScriptErrorsSuppressed = true,
                DocumentText = htmlContent//html字串
            };
             


            wb.DocumentCompleted += (sender, ee) =>
            {
                WebBrowser webBrowser = (WebBrowser)sender;

                if (width == 0)//呼叫端給0
                {//預設值
                    width = webBrowser.Document.Body.ScrollRectangle.Width+100;//加100自己微調
                }
                if (height == 0)
                {
                    height = webBrowser.Document.Body.ScrollRectangle.Height;
                }

                webBrowser.Width = width;
                webBrowser.Height = height;

                using (Bitmap bitmap = new Bitmap(width, height))//準備畫布
                {//webBrowser截圖至畫布
                    webBrowser.DrawToBitmap(bitmap, new Rectangle(0, 0, width, height));
                    bitmap.Save(gifFilePath, ImageFormat.Gif);//低品質圖片儲存法,將就使用XD
                }

            };

            //Console.WriteLine(wb.ReadyState.ToString());//debug
            while (wb.ReadyState != WebBrowserReadyState.Complete) { System.Windows.Forms.Application.DoEvents(); }
            //Console.WriteLine(wb.ReadyState.ToString());//debug
            wb.Dispose();
             

        });
        th.SetApartmentState(ApartmentState.STA); /*因為用到WebBrowser,所以加上STA*/
        th.Start();
        th.Join();//執行緒做完才能下個動作

    }
}

在 *.aspx.cs中的叫用方法↓

using System;
using System.Configuration;

public partial class GifTest : System.Web.UI.Page
{
    string WebBaseUrl = ConfigurationManager.AppSettings["WebBaseUrl"];
	 
    /// <summary>
    /// 依自己情況修改↓
    /// </summary>
    string PathGif = @"S:\CoverPage-"+DateTime.Now.ToString("yyyyMMddHHmmss")+".gif";//產出的gif檔案路徑

    //WebBrowser的width、height
    readonly int width = 1000;//固定寬
    readonly int height = 0;//自適應高

    protected void Page_Load(object sender, EventArgs e)
    {
		 
        string gifUrl = "https://www.pchome.com.tw/"; 
        //網頁截圖並儲存在主機上
        MyWebUtily.webBrowser_ScreenShotToGif(gifUrl, PathGif,this.width, this.height);
      
    }



}

 

文章參考

How to render Html content into JPG/JPEG image in best quality (WinForms)

Convert a specific part of html to image using WebBrowser

Convert HTML to Image in C#