前言
前段時間有同學在微信群裡提問,要使用.NET開發一個簡單的爬蟲功能但是沒有做過無從下手。今天給大家推薦一個輕量、靈活、高效能、跨平臺的分散式網路爬蟲框架(可以幫助 .NET 工程師快速的完成爬蟲的開發):DotnetSpider。
注意:為了自身安全請在國家法律允許範圍內開發網路爬蟲功能。
框架設計圖
整個爬蟲設計是純非同步的,利用訊息佇列進行各個元件的解耦,若是隻需要單機爬蟲則不需要做任何額外的配置,預設使用了一個記憶體型的訊息佇列;若是想要實現一個純分散式爬蟲,則需要引入一個訊息佇列即可,後面會詳細介紹如何實現一個分散式爬蟲。
框架原始碼
開發爬蟲需求
爬取部落格園10天推薦排行第一頁的文章標題、文章簡介和文章地址,並將其儲存到對應的txt文字中。
快速開始
建立SpiderSample控制檯
安裝DotnetSpider Nuget包
搜尋:DotnetSpider
新增Serilog日誌元件
搜尋:Serilog.AspNetCore
RecommendedRankingModel
public class RecommendedRankingModel
{
/// <summary>
/// 文章標題
/// </summary>
public string ArticleTitle { get; set; }
/// <summary>
/// 文章簡介
/// </summary>
public string ArticleSummary { get; set; }
/// <summary>
/// 文章地址
/// </summary>
public string ArticleUrl { get; set; }
}
RecommendedRankingSpider
public class RecommendedRankingSpider : Spider
{
public RecommendedRankingSpider(IOptions<SpiderOptions> options,
DependenceServices services,
ILogger<Spider> logger) : base(options, services, logger)
{
}
public static async Task RunAsync()
{
var builder = Builder.CreateDefaultBuilder<RecommendedRankingSpider>();
builder.UseSerilog();
builder.UseDownloader<HttpClientDownloader>();
builder.UseQueueDistinctBfsScheduler<HashSetDuplicateRemover>();
await builder.Build().RunAsync();
}
protected override async Task InitializeAsync(CancellationToken stoppingToken = default)
{
// 新增自定義解析
AddDataFlow(new Parser());
// 使用控制檯儲存器
AddDataFlow(new ConsoleStorage());
// 新增採集請求
await AddRequestsAsync(new Request("https://www.cnblogs.com/aggsite/topdiggs")
{
// 請求超時10秒
Timeout = 10000
});
}
class Parser : DataParser
{
public override Task InitializeAsync()
{
return Task.CompletedTask;
}
protected override Task ParseAsync(DataFlowContext context)
{
var recommendedRankingList = new List<RecommendedRankingModel>();
// 網頁資料解析
var recommendedList = context.Selectable.SelectList(Selectors.XPath(".//article[@class='post-item']"));
foreach (var news in recommendedList)
{
var articleTitle = news.Select(Selectors.XPath(".//a[@class='post-item-title']"))?.Value;
var articleSummary = news.Select(Selectors.XPath(".//p[@class='post-item-summary']"))?.Value?.Replace("\n", "").Replace(" ", "");
var articleUrl = news.Select(Selectors.XPath(".//a[@class='post-item-title']/@href"))?.Value;
recommendedRankingList.Add(new RecommendedRankingModel
{
ArticleTitle = articleTitle,
ArticleSummary = articleSummary,
ArticleUrl = articleUrl
});
}
using (StreamWriter sw = new StreamWriter("recommendedRanking.txt"))
{
foreach (RecommendedRankingModel model in recommendedRankingList)
{
string line = $"文章標題:{model.ArticleTitle}\r\n文章簡介:{model.ArticleSummary}\r\n文章地址:{model.ArticleUrl}";
sw.WriteLine(line+ "\r\n ==========================================================================================");
}
}
return Task.CompletedTask;
}
}
}
Program呼叫
internal class Program
{
static async Task Main(string[] args)
{
Console.WriteLine("Hello, World!");
await RecommendedRankingSpider.RunAsync();
Console.WriteLine("資料抓取完成");
}
}
抓取資料和頁面資料對比
抓取資料:
頁面資料:
專案原始碼地址
更多專案實用功能和特性歡迎前往專案開源地址檢視👀,別忘了給專案一個Star支援💖。
GitHub原始碼地址:https://github.com/dotnetcore/DotnetSpider
GitHub wiki:https://github.com/dotnetcore/DotnetSpider/wiki
優秀專案和框架精選
該專案已收錄到C#/.NET/.NET Core優秀專案和框架精選中,關注優秀專案和框架精選能讓你及時瞭解C#、.NET和.NET Core領域的最新動態和最佳實踐,提高開發工作效率和質量。坑已挖,歡迎大家踴躍提交PR推薦或自薦(讓優秀的專案和框架不被埋沒🤞
)。
https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md
DotNetGuide技術社群交流群
- DotNetGuide技術社群是一個面向.NET開發者的開源技術社群,旨在為開發者們提供全面的C#/.NET/.NET Core相關學習資料、技術分享和諮詢、專案推薦、招聘資訊和解決問題的平臺。
- 在這個社群中,開發者們可以分享自己的技術文章、專案經驗、遇到的疑難技術問題以及解決方案,並且還有機會結識志同道合的開發者。
- 我們致力於構建一個積極向上、和諧友善的.NET技術交流平臺,為廣大.NET開發者帶來更多的價值和成長機會。