• .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技术社区微信交流群👨‍👩‍👦

  • 相关阅读:
    操作系统 | 实验七 SPOOLING技术
    设备管理团队如何做好停机维护工作_基于PreMaint设备数字化平台
    1.Hadoop集群的配置
    我发布了一款基于RBAC权限模型实现的通用后台管理系统
    【Factory模式】C++设计模式——工厂模式
    C进阶-语言文件操作
    父组件调用子组件中的方法(vue2)
    智能合约提款和转账错误
    JavaScript 开发的历程
    静态网卡配置centos、kali、ubantu
  • 原文地址:https://www.cnblogs.com/Can-daydayup/p/18208192