.NET使用分散式網路爬蟲框架DotnetSpider快速開發爬蟲功能

追逐時光者發表於2023-12-08

前言

前段時間有同學在微信群裡提問,要使用.NET開發一個簡單的爬蟲功能但是沒有做過無從下手。今天給大家推薦一個輕量、靈活、高效能、跨平臺的分散式網路爬蟲框架(可以幫助 .NET 工程師快速的完成爬蟲的開發):DotnetSpider。

注意:為了自身安全請在國家法律允許範圍內開發網路爬蟲功能。

框架設計圖

整個爬蟲設計是純非同步的,利用訊息佇列進行各個元件的解耦,若是隻需要單機爬蟲則不需要做任何額外的配置,預設使用了一個記憶體型的訊息佇列;若是想要實現一個純分散式爬蟲,則需要引入一個訊息佇列即可,後面會詳細介紹如何實現一個分散式爬蟲。

框架原始碼

開發爬蟲需求

爬取部落格園10天推薦排行第一頁的文章標題、文章簡介和文章地址,並將其儲存到對應的txt文字中。

請求地址:https://www.cnblogs.com/aggsite/topdiggs

快速開始

建立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開發者帶來更多的價值和成長機會。

歡迎加入DotNetGuide技術社群微信交流群👪

 

相關文章