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

前言

前段時間有同學在微信羣裏提問,要使用.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技術社區微信交流羣👪

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章