首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C# 實現網頁內容抓取:WebClient 與 HttpClient 方案對比

     編輯:關於C語言

核心類演進

  • WebClient:.NET Framework 早期高級封裝,同步 API 為主,已標記為過時(不建議新項目使用)
  • HttpClient:.NET 4.5+ 推薦,異步優先、可復用、支持現代 HTTP 特性
  • HttpWebRequest:底層控制,靈活但繁瑣,現罕用

方案一:WebClient (舊代碼維護參考)

ASP.NET 頁面版


<%@ Page Language="C#" %>
<%@ Import Namespace="System.Net" %>
<%@ Import Namespace="System.Text" %>

控制台版


using System;
using System.Net;
using System.Text;

class Program
{
    static void Main()
    {
        try
        {
            using (WebClient client = new WebClient())
            {
                client.Credentials = CredentialCache.DefaultCredentials;
                byte[] data = client.DownloadData("https://blog.example.com");
                string html = Encoding.UTF8.GetString(data);
                Console.WriteLine(html);
            }
        }
        catch (WebException ex)
        {
            Console.WriteLine($"抓取失敗: {ex.Message}");
        }
    }
}

方案二:HttpClient (現代標準,強烈推薦)

基礎異步獲取


using System;
using System.Net.Http;
using System.Threading.Tasks;

class Program
{
    // 靜態單例模式,避免 Socket 耗盡
    private static readonly HttpClient _client = new HttpClient()
    {
        Timeout = TimeSpan.FromSeconds(30)
    };
    
    static async Task Main()
    {
        try
        {
            string url = "https://api.example.com/data";
            // 自動處理壓縮、重定向、編碼檢測
            string html = await _client.GetStringAsync(url);
            Console.WriteLine(html);
        }
        catch (HttpRequestException ex)
        {
            Console.WriteLine($"網絡錯誤: {ex.Message}");
        }
        catch (TaskCanceledException)
        {
            Console.WriteLine("請求超時");
        }
    }
}

進階:自定義 Header、Cookie、User-Agent


var handler = new HttpClientHandler
{
    AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate,
    CookieContainer = new CookieContainer(),
    UseCookies = true
};

using (var client = new HttpClient(handler))
{
    client.DefaultRequestHeaders.UserAgent.ParseAdd("Mozilla/5.0 (compatible; MyBot/1.0)");
    client.DefaultRequestHeaders.Referrer = new Uri("https://www.google.com/");
    
    var response = await client.GetAsync(url);
    response.EnsureSuccessStatusCode(); // 拋異常如果非 2xx
    
    // 手動處理編碼(GetStringAsync 已自動按 Content-Type charset 解碼)
    string html = await response.Content.ReadAsStringAsync();
}

下載二進制文件 (圖片、PDF)


byte[] fileBytes = await _client.GetByteArrayAsync("https://example.com/image.png");
await File.WriteAllBytesAsync("image.png", fileBytes);

編碼自動檢測最佳實踐

WebClient.DownloadData 返回原始字節,需手動指定編碼。HttpClient.GetStringAsync / ReadAsStringAsync 會自動讀取 Content-Type: text/html; charset=utf-8 中的 charset,若無則嘗試從 HTML `` 推斷(需 .NET 6+ 或第三方庫)。

若遇到無 charset 頁面,可用 Ude.NetStandard 或 EncodingDetector 庫檢測:


byte[] raw = await _client.GetByteArrayAsync(url);
string html = EncodingDetector.DetectAndDecode(raw); // 第三方庫

反爬蟲應對基礎

策略代碼示例
隨機 User-Agent維護 UA 池,每次請求隨機選取
請求間隔await Task.Delay(Random.Next(1000, 3000))
Cookie 持久化CookieContainer 跨請求共享
代理 IPHttpClientHandler.Proxy = new WebProxy("ip:port")
處理 JS 渲染需引入 Selenium/Playwright/PuppeteerSharp

法律與道德提醒

  • 遵守 robots.txt 與網站服務條款
  • 控制抓取頻率,不影響目標站點正常服務
  • 僅抓取公開數據,勿繞過登錄/驗證碼/加密接口
  • 商業用途請獲取授權或使用官方 API

總結

新項目請直接使用 HttpClient(單例模式)配合 async/await。WebClient 僅用於維護 .NET Framework 老舊代碼。抓取中文頁面時注意編碼自動檢測,複雜動態頁面需引入瀏覽器自動化工具。務必合法合規使用。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved