• .NET快速实现网页数据抓取


    前言

    今天我们来讲讲如何使用.NET开源(MIT License)的轻量、灵活、高性能、跨平台的分布式网络爬虫框架DotnetSpider来快速实现网页数据抓取功能。

    注意:为了自身安全请在国家法律允许范围内开发网页爬虫功能。

    网页数据抓取需求

    本文我们以抓取博客园10天推荐排行榜第一页的文章标题、文章简介和文章地址为示例,并把抓取下来的数据保存到对应的txt文本中。

    创建控制台应用

    创建名为DotnetSpiderExercise的控制台应用。

    安装DotnetSpider NuGet包

    NuGet包管理器搜索:DotnetSpider

    添加Serilog日志组件

    NuGet包管理器搜索:Serilog.AspNetCore

    添加RecommendedRankingModel

    namespace DotnetSpiderExercise
    {
        public class RecommendedRankingModel
        {
            /// 
            /// 文章标题
            /// 
            public string ArticleTitle { getset; }
    
            /// 
            /// 文章简介
            /// 
            public string ArticleSummary { getset; }
    
            /// 
            /// 文章地址
            /// 
            public string ArticleUrl { getset; }
        }
    }
    

    添加RecommendedRankingSpider

    网页数据抓取的业务逻辑都在这里面。

    using DotnetSpider.DataFlow.Parser;
    using DotnetSpider.DataFlow;
    using DotnetSpider.Downloader;
    using DotnetSpider.Http;
    using DotnetSpider.Scheduler.Component;
    using DotnetSpider.Selector;
    using DotnetSpider;
    using Microsoft.Extensions.Logging;
    using Microsoft.Extensions.Options;
    using Serilog;
    using DotnetSpider.Scheduler;
    using Microsoft.Extensions.Hosting;
    using System.Reflection;
    
    namespace DotnetSpiderExercise
    {
        public class RecommendedRankingSpider : Spider
        {
            public RecommendedRankingSpider(IOptions options,
                DependenceServices services,
                ILogger logger) : base(options, services, logger)
            {
            }
    
            public static async Task RunAsync()
            {
                var builder = Builder.CreateDefaultBuilder();
                builder.UseSerilog();
                builder.UseDownloader();
                builder.UseQueueDistinctBfsScheduler();
                await builder.Build().RunAsync();
            }
    
            protected override async Task InitializeAsync(CancellationToken stoppingToken = default)
            {
                //添加自定义解析
                AddDataFlow(new Parser());
                //使用控制台存储器
                AddDataFlow(new ConsoleStorage());
                //添加采集请求:博客园10天推荐排行榜
                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();
                    // 网页数据解析
                    var number = 1;
                    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;
    
                        Console.WriteLine($"第{number}篇文章 标题:{articleTitle}");
    
                        recommendedRankingList.Add(new RecommendedRankingModel
                        {
                            ArticleTitle = articleTitle,
                            ArticleSummary = articleSummary,
                            ArticleUrl = articleUrl
                        });
    
                        number++;
                    }
    
                    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 ========================================================================================== \r\n");
                        }
                    }
                    return Task.CompletedTask;
                }
            }
        }
    }
    

    Program执行数据抓取

    namespace DotnetSpiderExercise
    {
        public class Program
        {
            static async Task Main(string[] args)
            {
                Console.WriteLine("网页数据抓取开始...");
    
                await RecommendedRankingSpider.RunAsync();
    
                Console.WriteLine("网页数据抓取完成...");
            }
        }
    }
    

    抓取数据和页面数据对比

    抓取数据

    页面数据

    项目源码地址

    更多项目实用功能和特性欢迎前往项目开源地址查看👀,别忘了给项目一个Star支持💖。

    优秀项目和框架精选

    该项目已收录到C#/.NET/.NET Core优秀项目和框架精选中,关注优秀项目和框架精选能让你及时了解C#、.NET和.NET Core领域的最新动态和最佳实践,提高开发工作效率和质量。坑已挖,欢迎大家踊跃提交PR推荐或自荐(让优秀的项目和框架不被埋没🤞)。

    DotNetGuide技术社区交流群

    • DotNetGuide技术社区是一个面向.NET开发者的开源技术社区,旨在为开发者们提供全面的C#/.NET/.NET Core相关学习资料、技术分享和咨询、项目框架推荐、求职和招聘资讯、以及解决问题的平台。
    • 在DotNetGuide技术社区中,开发者们可以分享自己的技术文章、项目经验、学习心得、遇到的疑难技术问题以及解决方案,并且还有机会结识志同道合的开发者。
    • 我们致力于构建一个积极向上、和谐友善的.NET技术交流平台。无论您是初学者还是有丰富经验的开发者,我们都希望能为您提供更多的价值和成长机会。

    欢迎加入DotNetGuide技术社区微信交流群👨‍👩‍👦

  • 相关阅读:
    测试用例的编写(面试常问)
    Android studio进入手机调试状态
    AnyLogic 8.8.4:遗传优化和步行电梯 AnyLogic 8.8.5
    案例 | 美创助力镇海区大数据发展管理中心构建“数改”安全防护力
    Nginx请求处理时间过长问题解决
    idea 导入项目
    Javascript Summery3 TOUCH SCREEN COMMON CSS
    保姆级 C++ 学习路线
    【毕业设计】基于单片机的智能避障扫地机器人 -物联网 嵌入式
    计算机网络原理
  • 原文地址:https://www.cnblogs.com/Can-daydayup/p/18208192