C# 网页内容抓取方法 C#如何爬取网页数据

来源:这里教程网 时间:2026-02-21 17:39:46 作者:

HttpClient
获取网页 HTML 最直接可靠

现代 C# 爬虫首选

HttpClient
,它支持异步、自动处理重定向和 Cookie(需手动配置),比已过时的
WebClient
更稳定。同步调用(
DownloadString
)在 .NET 6+ 中已被标记为过时,必须用
GetAsync
+
ReadAsStringAsync

常见错误:忽略响应状态码,直接读取内容,导致空字符串或异常;或未设置

User-Agent
被服务器拒绝(返回 403)。

务必检查
response.IsSuccessStatusCode
,否则 404/500 也会进后续解析流程
添加请求头:
client.DefaultRequestHeaders.UserAgent.ParseAdd("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36")
若目标页依赖 JavaScript 渲染,
HttpClient
拿到的是原始 HTML,无法获取动态内容——此时不是代码问题,而是技术选型错误
var client = new HttpClient();
client.DefaultRequestHeaders.UserAgent.ParseAdd("Mozilla/5.0 (Windows NT 10.0; Win64; x64)");
var response = await client.GetAsync("https://example.com");
if (!response.IsSuccessStatusCode)
    throw new Exception($"HTTP {response.StatusCode}");
var html = await response.Content.ReadAsStringAsync();

HtmlAgilityPack
解析 HTML 结构

HtmlAgilityPack
是 C# 生态中事实标准的 HTML 解析库,能容忍 malformed HTML(如缺失闭合标签),比正则匹配安全得多。NuGet 包名就是
HtmlAgilityPack
,.NET Core / .NET 5+ 全支持。

容易踩的坑:直接对

html
字符串调用
LoadHtml()
却忽略编码问题,中文乱码;或用
SelectNodes("//div[@class='item']")
但没确认节点是否为
null
就访问
InnerText
,引发
NullReferenceException

加载前显式指定编码(尤其 GB2312/GBK 页面):
doc.LoadHtml(html, Encoding.GetEncoding("gb2312"))
所有
SelectNodes
SelectSingleNode
返回值必须判空,再取
InnerText
GetAttributeValue
XPath 中 class 属性含空格或多值时,用
contains(@class, 'xxx')
@class='xxx'
更鲁棒
var doc = new HtmlDocument();
doc.LoadHtml(html);
var nodes = doc.DocumentNode.SelectNodes("//div[contains(@class, 'title')]");
if (nodes != null)
    foreach (var node in nodes)
        Console.WriteLine(node.InnerText.Trim());

绕过反爬:处理 Cookie、Referer 和简单 JS 挑战

多数静态页面只需加

User-Agent
Referer
;但遇到登录态依赖或基础 JS 检查(如生成时间戳、计算 token),就得维持会话上下文。

关键点:用同一个

HttpClient
实例复用连接和 Cookie 容器,不要每次新建;
HttpClientHandler
UseCookies = true
必须开启(默认是 true,但显式写上更安心)。

Referer
头要与目标 URL 同域,否则部分站点拒收(例如从
https://a.com
请求
https://b.com/api
会被拦截)
若首次请求返回
Set-Cookie
,后续请求自动携带——前提是没换
HttpClient
实例
遇到
document.cookie = xxx
Math.random()
生成参数,不能硬编码,得用
JavaScriptEngineSwitcher
或预编译 JS 片段(小范围可行),否则应转向 PuppeteerSharp

何时该换
PuppeteerSharp

当目标页面大量使用

fetch
Vue/React
渲染、或有滑动验证、鼠标轨迹检测时,
HttpClient + HtmlAgilityPack
就失效了。这时候
PuppeteerSharp
(Chromium 自动化)是更实际的选择,而非强行逆向加密逻辑。

注意:它体积大(约 80MB Chromium 二进制)、启动慢、内存占用高,不适合高频轻量采集;且需要确保运行环境有可用的 Chromium(或启用

DownloadBrowser = true
自动下载)。

首次运行会自动下载 Chromium,耗时长且可能失败(国内网络需配代理或手动下载) 务必调用
browser.CloseAsync()
DisposeAsync()
,否则残留进程吃光内存
等待元素出现用
WaitForSelectorAsync("div.content")
,别用
Thread.Sleep

真实场景里,90% 的企业内网报表、政府公开数据页,

HttpClient
足够;剩下 10% 才需要评估是否值得引入 PuppeteerSharp。

相关推荐