面向:使用 Aneiang.Pa 进行热榜/动态爬取,希望在生产环境里更稳定地跑任务,并通过 ASP.NET Core Web API 对外提供统一接口的同学。
项目地址:
Aneiang.Pa 是一个开箱即用的 .NET 爬虫库,支持多平台热榜爬取,同时也提供更灵活的动态数据集爬取(Aneiang.Pa.Dynamic)。在真实网络环境中,爬虫经常会遇到 限流、封禁、网络抖动 等问题,因此项目新增了两块非常实用的能力:
- 代理池(Proxy Pool):配置多个代理,自动轮询/随机切换,降低单 IP 风险。
- ASP.NET Core Web API 集成(Aneiang.Pa.AspNetCore):提供现成的 RESTful 控制器,把爬虫能力"服务化"。
下面用一篇完整的实战文章,把两者如何落地串起来。
1. 为什么需要代理池?
在抓取公开站点时,常见的失败原因包括:
- 访问频率偏高导致 IP 被封
- 目标站点按 IP / 地域做 风控
- 特定出口网络不稳定,导致 超时 或 连接失败
代理池的价值在于:
- 把请求出口分摊到多个代理上
- 可按策略(轮询/随机)切换代理
- 支持带认证代理(用户名密码)
注意:仍建议控制抓取间隔(例如 5 分钟以上),代理池不是"无限高频"的免死金牌。
2. 代理池能力概览(Aneiang.Pa.Core)
Aneiang.Pa 的代理池支持:
- ✅ 多代理配置
- ✅ 两种选择策略
RoundRobin:轮询(负载更均衡)Random:随机(更分散)
- ✅ 带认证代理:
http://user:password@host:port - ✅ 可通过配置文件或代码配置
- ✅ 未启用时自动退化为普通
HttpClient
3. 在应用中启用代理池(推荐:配置文件方式)
3.1 appsettings.json 配置
在你的应用(Console/Worker/WebAPI 都行)的 appsettings.json 加入:
json
{
"Scraper": {
"ProxyPool": {
"Enabled": true,
"Strategy": "RoundRobin",
"Proxies": [
"http://127.0.0.1:7890",
"http://user:password@proxy.example.com:8080",
"http://192.168.1.100:3128"
]
}
}
}
3.2 注册带代理池的默认 HttpClient
在 .NET 的依赖注入里,先注册带代理池的默认 HttpClient,再注册爬虫服务:
csharp
using Aneiang.Pa.Core.Proxy;
var builder = Host.CreateDefaultBuilder(args)
.ConfigureServices((context, services) =>
{
// 注册带代理池支持的默认 HttpClient
services.AddPaDefaultHttpClientWithProxy(
proxyConfiguration: context.Configuration.GetSection("Scraper:ProxyPool"));
// 注册爬虫服务(会自动使用配置的 HttpClient)
services.AddNewsScraper(context.Configuration);
})
.Build();
关键点:
- 默认 HttpClient 名称:
Aneiang.Pa.DefaultHttpClient - 先 调用
AddPaDefaultHttpClientWithProxy,再AddNewsScraper,爬虫才能自动用上代理池。
4. 代码方式配置代理池(更灵活)
如果你希望代理列表来自数据库、环境变量或运行时拼装,也可以用代码配置:
csharp
using Aneiang.Pa.Core.Proxy;
services.AddPaDefaultHttpClientWithProxy(
proxyConfigure: options =>
{
options.Enabled = true;
options.Strategy = ProxySelectionStrategy.RoundRobin; // 或 Random
options.Proxies = new List<string>
{
"http://127.0.0.1:7890",
"http://user:password@proxy.example.com:8080",
"http://192.168.1.100:3128"
};
});
services.AddNewsScraper();
5. 仅使用代理池服务(不接管 HttpClient)
有些场景你可能只想"拿到一个代理地址",自己去构建请求(比如你有自己的 HttpClientFactory 策略)。这时可以只注册代理池:
csharp
services.AddPaProxyPool(
configure: options =>
{
options.Enabled = true;
options.Strategy = ProxySelectionStrategy.Random;
options.Proxies = new List<string> { "http://127.0.0.1:7890" };
});
// 使用
var proxyPool = serviceProvider.GetRequiredService<IProxyPool>();
var proxyUri = proxyPool.GetNextProxy();
6. 把爬虫"服务化":ASP.NET Core Web API 集成
当你希望把爬虫能力提供给前端、其他服务或自动化任务时,最省事的方式就是引入 Aneiang.Pa.AspNetCore。
6.1 安装包
bash
dotnet add package Aneiang.Pa.AspNetCore
6.2 注册服务与控制器
在 Program.cs(Minimal Hosting)中:
csharp
using Aneiang.Pa.Extensions;
using Aneiang.Pa.AspNetCore.Extensions;
var builder = WebApplication.CreateBuilder(args);
// 1) 注册爬虫服务
builder.Services.AddNewsScraper(builder.Configuration);
// 2) 添加爬虫控制器支持
builder.Services.AddScraperController(options =>
{
options.RoutePrefix = "api/scraper"; // 默认也是 api/scraper
options.UseLowercaseInRoute = true; // 路由使用小写
options.EnableResponseCaching = false; // 是否启用响应缓存
options.CacheDurationSeconds = 300; // 缓存时长(秒)
});
var app = builder.Build();
app.MapControllers();
app.Run();
如果你还想让 Web API 的爬虫请求也走代理池,把前面"代理池 HttpClient 注册"加进来,并确保顺序正确:
csharp
using Aneiang.Pa.Core.Proxy;
using Aneiang.Pa.Extensions;
using Aneiang.Pa.AspNetCore.Extensions;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddPaDefaultHttpClientWithProxy(
proxyConfiguration: builder.Configuration.GetSection("Scraper:ProxyPool"));
builder.Services.AddNewsScraper(builder.Configuration);
builder.Services.AddScraperController();
var app = builder.Build();
app.MapControllers();
app.Run();
7. 现成 API 端点一览
启用控制器后,默认提供以下 RESTful API:
| 端点 | 方法 | 说明 | 示例 |
|---|---|---|---|
/api/scraper/{source} |
GET | 获取指定平台的新闻 | /api/scraper/BaiDu |
/api/scraper/available-sources |
GET | 获取所有支持的爬虫源列表 | /api/scraper/available-sources |
/api/scraper/health |
GET | 检查所有爬虫健康状态 | /api/scraper/health?timeoutMs=5000 |
/api/scraper/{source}/health |
GET | 检查指定爬虫健康状态 | /api/scraper/BaiDu/health?timeoutMs=5000 |
支持的爬虫源(大小写不敏感):
BaiDu、Bilibili、WeiBo、ZhiHu、DouYin、HuPu、TouTiao、Tencent、JueJin、ThePaper、DouBan、IFeng、Csdn、CnBlog
8. (可选)为 Web API 增加授权:ApiKey / 自定义 / 混合
默认授权是关闭的(Enabled = false),即接口可公开访问。
8.1 配置文件方式(推荐)
appsettings.json:
json
{
"Scraper": {
"Authorization": {
"Enabled": true,
"Scheme": "ApiKey",
"ApiKeys": [
"your-api-key-1",
"your-api-key-2"
],
"ApiKeyHeaderName": "X-API-Key",
"ApiKeyQueryParameterName": "apiKey",
"ExcludedRoutes": [
"/api/scraper/health",
"/api/scraper/available-sources"
],
"UnauthorizedMessage": "未授权访问"
}
}
}
然后在代码中启用:
csharp
builder.Services.ConfigureAuthorization(builder.Configuration);
8.2 调用示例
通过请求头:
bash
curl -H "X-API-Key: your-api-key-1" https://your-api.com/api/scraper/BaiDu
通过 query:
bash
curl https://your-api.com/api/scraper/BaiDu?apiKey=your-api-key-1
9. 组合实战:带代理池的 Web API 爬虫服务
把它们组合起来,你会得到一个典型的生产结构:
- Web API 对外提供统一爬虫服务
- 内部所有抓取请求自动使用代理池
- 可选加上 ApiKey 鉴权
- 健康检查端点用于运维探活
一个常见的落地建议:
- 把
/api/scraper/available-sources、/api/scraper/health作为公开端点(或仅内网访问) - 业务抓取端点
/api/scraper/{source}建议开启鉴权 - 配合网关(Nginx / APISIX / YARP)做限流、缓存和观测
10. 注意事项与最佳实践
- 空代理列表校验 :
Enabled=true但没有配置Proxies会抛异常,确保配置完整。 - 策略选择 :
- 代理质量相近:优先
RoundRobin - 代理质量参差 / 想更分散:用
Random
- 代理质量相近:优先
- 抓取频率:代理池不是"无限频率",仍建议控制间隔(例如 5 分钟+)。
- 可观测性:建议在上层接入日志与指标(请求失败率、超时、代理切换频率等),便于定位坏代理。
结语
代理池解决了"出口稳定性"的问题,ASP.NET Core 集成解决了"对外服务化"的问题,两者结合可以让 Aneiang.Pa 从一个库,快速变成可部署、可运维、可被其他系统调用的抓取服务。
如果你接下来还希望增强生产能力,可以继续扩展:
- 代理健康检查与自动剔除(坏代理淘汰)
- 缓存策略(本地缓存/分布式缓存)
- 任务调度(Quartz / Hangfire)与异步队列
- 站点级别限流与重试策略