功能丰富的 .NET 模块化爬虫库
将爬虫分为「热榜」和「特定领域」两大类。用统一 API 接入微博、知乎、B 站等平台的热榜数据,并提供彩票数据、动态爬虫等灵活的领域爬虫。内置代理池、健康检查、ASP.NET Core API 扩展,为生产环境提供稳定支持。
⚠️ 抓取间隔建议控制在 五分钟以上,请勿用于商业售卖或任何违法用途。
// 注册爬虫服务与代理池
using Aneiang.Pa.Extensions;
using Aneiang.Pa.Core.Proxy;
var builder = WebApplication.CreateBuilder(args);
// 可选:配置代理池,减少 IP 被封风险
builder.Services.AddPaDefaultHttpClientWithProxy(
proxyConfiguration: builder.Configuration.GetSection("Scraper:ProxyPool"));
// 注册多平台新闻爬虫
builder.Services.AddNewsScraper(builder.Configuration);
var app = builder.Build();
app.MapGet("/hot/{source}", async (string source, INewsScraperFactory factory) =>
{
var scraper = factory.GetScraper(source);
return Results.Ok(await scraper.GetNewsAsync());
});
app.Run();
核心特性
面向真实线上使用场景设计,从「易用性」「可扩展性」「生产环境友好」三个维度做了权衡。
内置「热榜」和「特定领域」两大类爬虫。热榜模块统一了微博、知乎、B 站等十多个平台的数据接口;特定领域模块则提供了彩票数据、动态爬虫等更灵活的功能。
内置代理池组件,支持轮询与随机策略,有效降低 IP 封禁风险。同时提供 Web API 健康检查端点,便于对各平台爬虫的可用性进行快速诊断和监控。
提供
Aneiang.Pa.AspNetCore
扩展包,可快速暴露 RESTful API。通过
Aneiang.Pa.Dynamic
动态爬虫,可通过特性声明灵活定义任意站点的数据集,轻松扩展新平台。
支持平台
按需引用单个平台的 NuGet 包,或直接使用聚合包
Aneiang.Pa
一次性接入全部平台。
安装与使用
我们推荐使用全局聚合包快速上手,同时也支持按需引用单个功能模块。
1. 安装 NuGet 包
# 安装全局聚合包(推荐)
dotnet add package Aneiang.Pa
# 或仅安装热榜聚合包
dotnet add package Aneiang.Pa.News
2. 注册服务
using Aneiang.Pa.Extensions;
// 注册所有爬虫(推荐)
services.AddPaScraper();
// 或按需注册
// services.AddNewsScraper();
// services.AddLotteryScraper();
3. 使用爬虫
// 获取热榜数据
var factory = provider.GetRequiredService<INewsScraperFactory>();
var scraper = factory.GetScraper(ScraperSource.BaiDu);
var news = await scraper.GetNewsAsync();
// 获取彩票数据
var lotteryScraper = provider.GetRequiredService<ILotteryScraper>();
var ssq = await lotteryScraper.GetLotteryDataAsync(LotteryType.SSQ);
// 使用动态爬虫
var dynamicScraper = provider.GetRequiredService<IDynamicScraper>();
var posts = await dynamicScraper.DatasetScraper<MyModel>("https://example.com");
代理池(Proxy Pool)
当需要大规模、持续性抓取数据时,建议启用代理池功能,以降低 IP 被封禁风险。
配置文件方式(推荐)
// appsettings.json
{
"Scraper": {
"ProxyPool": {
"Enabled": true,
"Strategy": "RoundRobin",
"Proxies": [
"http://127.0.0.1:7890",
"http://user:password@proxy.example.com:8080"
]
}
}
}
在代码中注册
using Aneiang.Pa.Core.Proxy;
builder.Services.AddPaDefaultHttpClientWithProxy(
proxyConfiguration: builder.Configuration.GetSection("Scraper:ProxyPool"));
// 然后正常注册爬虫服务
builder.Services.AddNewsScraper(builder.Configuration);
支持
RoundRobin
与
Random
两种策略,未启用时自动退化为普通 HttpClient。
ASP.NET Core Web API 集成
使用
Aneiang.Pa.AspNetCore
可以快速暴露标准化 RESTful API,
并支持“爬取数据缓存”(None / Memory / Redis)与可选授权(ApiKey / Custom / Combined)。
安装扩展包
dotnet add package Aneiang.Pa.AspNetCore
注册控制器
using Aneiang.Pa.AspNetCore.Extensions;
using Aneiang.Pa.News.Extensions;
using Aneiang.Pa.Lottery.Extensions;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
// 业务服务(热榜/彩票等)
builder.Services.AddNewsScraper(builder.Configuration);
builder.Services.AddLotteryScraper();
// 1) 注册 API + 缓存(读取 Scraper 配置节)
builder.Services.AddPaScraperApi(builder.Configuration);
// 2) 如需授权再启用(读取 Scraper:Authorization 配置节,支持可选代码覆盖)
builder.Services.AddPaScraperAuthorization(builder.Configuration);
var app = builder.Build();
app.MapControllers();
app.Run();
可用 API 端点
-
GET /api/scraper/news/{source}· 获取指定平台热榜 -
GET /api/scraper/news/sources· 获取所有支持的热榜源 -
GET /api/scraper/lottery/welfare/{type}· 获取福利彩票开奖信息 -
GET /api/scraper/lottery/sport/{type}· 获取体育彩票开奖信息 -
GET /api/scraper/lottery/types· 获取所有支持的彩票类型 -
GET /api/scraper/health· 检查所有爬虫健康状态 -
GET /api/scraper/{source}/health· 检查指定爬虫健康状态
授权默认不启用;如需鉴权请显式调用
AddPaScraperAuthorization
。支持 ApiKey / Custom / Combined,并可配置排除路由。
动态爬虫(Aneiang.Pa.Dynamic)
不止是固定平台热榜,你可以通过特性标注快速声明任意网页的数据结构,实现高度可定制的数据采集。
安装与注册
dotnet add package Aneiang.Pa.Dynamic
services.AddDynamicScraper();
调用示例
var scraper = scope.ServiceProvider.GetRequiredService<IDynamicScraper>();
var result = await scraper.DatasetScraper<CnBlogOriginalResult>(
"https://www.cnblogs.com/pick");
模型定义示例(博客园热门)
[HtmlContainer("div", htmlClass: "post-list", htmlId: "post_list", index: 1)]
[HtmlItem("article", htmlClass: "post-item")]
public class CnBlogOriginalResult
{
[HtmlValue("a", htmlClass: "post-item-title")]
public string Title { get; set; }
[HtmlValue(".", attribute: "data-post-id")]
public string Id { get; set; }
[HtmlValue("a", htmlClass: "post-item-title", attribute: "href")]
public string Url { get; set; }
// ...更多字段定义
}
社区与合规
贡献与反馈
- 欢迎通过 PR / Issue 贡献新平台爬虫、解析优化或健壮性改进。
- 提交前请尽量保持代码风格一致,并附上必要说明与测试。
- 如果希望在官方 NuGet 包中发布你的平台实现,建议先在 Issue 中讨论设计方案。
使用合规声明
- 本项目仅用于个人学习、研究或公益目的。
- 请遵守目标网站的 robots 协议与相关法律法规,避免恶意、大规模、未经授权的爬取行为。
- 严禁将任何爬取数据用于商业售卖、攻击他人或其他违法用途,否则一切法律责任由使用者自行承担。