要写一个使用C#和HttpClient的爬虫程序。首先,我需要了解HttpClient的基本用法。HttpClient是用来发送HTTP请求和接收响应的类,对吧?我记得在C#中使用它的时候需要注意一些事情,比如最好使用单例实例,而不是频繁创建和销毁,这样可以避免端口耗尽的问题。

以下是使用C#和HttpClient
编写的爬虫程序示例,包含详细注释和扩展说明:
csharp
using System;
using System.Net.Http;
using System.Threading.Tasks;
using HtmlAgilityPack; // 需要安装NuGet包
class WebCrawler
{
private static readonly HttpClient _httpClient = new HttpClient();
static async Task Main(string[] args)
{
// 配置HTTP客户端
_httpClient.DefaultRequestHeaders.UserAgent.ParseAdd("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36");
_httpClient.Timeout = TimeSpan.FromSeconds(30);
try
{
string url = "https://example.com";
// 发送HTTP GET请求
HttpResponseMessage response = await _httpClient.GetAsync(url);
response.EnsureSuccessStatusCode(); // 检查状态码
// 读取响应内容
string htmlContent = await response.Content.ReadAsStringAsync();
// 解析HTML内容
var htmlDoc = new HtmlDocument();
htmlDoc.LoadHtml(htmlContent);
// 示例:提取所有链接
foreach (HtmlNode link in htmlDoc.DocumentNode.SelectNodes("//a[@href]"))
{
string hrefValue = link.GetAttributeValue("href", string.Empty);
Console.WriteLine($"发现链接: {hrefValue}");
}
// 示例:提取页面标题
string pageTitle = htmlDoc.DocumentNode.SelectSingleNode("//title")?.InnerText;
Console.WriteLine($"页面标题: {pageTitle}");
}
catch (HttpRequestException ex)
{
Console.WriteLine($"HTTP请求失败: {ex.Message}");
}
catch (TaskCanceledException ex)
{
Console.WriteLine($"请求超时: {ex.Message}");
}
catch (Exception ex)
{
Console.WriteLine($"发生错误: {ex.Message}");
}
}
}
关键组件说明
-
HttpClient配置
- 单例模式:避免短时间创建多个实例导致端口耗尽
- 用户代理:模拟浏览器行为避免被屏蔽
- 超时设置:30秒请求超时限制
-
HTML解析
- 使用HtmlAgilityPack(需通过NuGet安装)
- XPath查询语法提取特定元素
-
异常处理
- 专用HTTP异常处理
- 超时单独处理
- 通用异常捕获
扩展增强建议
-
代理支持
inivar handler = new HttpClientHandler { Proxy = new WebProxy("http://proxy-server:8080"), UseProxy = true }; var client = new HttpClient(handler);
-
请求限速
arduinoawait Task.Delay(TimeSpan.FromSeconds(2)); // 每次请求间隔
-
Cookie管理
inivar cookieContainer = new CookieContainer(); var handler = new HttpClientHandler { CookieContainer = cookieContainer };
-
内容过滤
lessif (hrefValue.EndsWith(".pdf")) // 过滤PDF文件
注意事项
-
法律合规
- 遵守目标网站的robots.txt协议
- 尊重版权和隐私条款
-
性能优化
- 使用
HttpClientFactory
(ASP.NET Core环境) - 并行请求控制
- 使用
-
反爬对策
- 随机化请求间隔
- 使用代理池轮换
- 处理验证码(需要额外服务)
安装HtmlAgilityPack:
csharp
dotnet add package HtmlAgilityPack
注意:C# 7.1+ 支持异步Main方法,需在.csproj中添加:
xml<PropertyGroup> <LangVersion>latest</LangVersion> </PropertyGroup>
这个爬虫框架可根据具体需求扩展更多功能,建议在实际使用中遵守目标网站的服务条款和相关法律法规。