.NET爬取美圖官網首頁數據實戰

来源:https://www.cnblogs.com/wml-it/archive/2023/08/14/17628041.html
-Advertisement-
Play Games

## 前言: 在當今信息化社會,網路數據分析越來越受到重視。而作為開發人員,掌握一門能夠抓取網頁內容的語言顯得尤為重要。在此篇文章中,將分享如何使用 .NET構建網路抓取工具。詳細瞭解如何執行 HTTP 請求來下載要抓取的網頁,然後從其 DOM 樹中選擇 HTML 元素,進行匹配需要的欄位信息,從中 ...


前言:

  在當今信息化社會,網路數據分析越來越受到重視。而作為開發人員,掌握一門能夠抓取網頁內容的語言顯得尤為重要。在此篇文章中,將分享如何使用 .NET構建網路抓取工具。詳細瞭解如何執行 HTTP 請求來下載要抓取的網頁,然後從其 DOM 樹中選擇 HTML 元素,進行匹配需要的欄位信息,從中提取數據。

一、準備工作:

創建項目:

​ 創建一個簡單的Winfrom客戶端程式,我使用的是.NET 5.0框架。為使項目顯得條理清晰,此處進行了項目分層搭建項目,也就是多建立幾個幾個類庫罷了,然後進行引用。

項目結構:
image

客戶端界面設計:

image

NuGet添加引用類庫HtmlAgilityPack:

HtmlAgilityPack是一個開源的C#庫,它允許你解析HTML文檔,從公DOM中選擇元素並提取數據。該工具基本上提供了抓取靜態內容網站所需要的一切。這是一個敏捷的HTML解析器,它構建了一個讀和寫DOM,並支持普通的XPATH或XSLT,你實際上不必瞭解XPATH也不必瞭解XSLT就可以使用它。它是一個.NET代碼庫,允許你解析“Web外”的HTML文件。解析器對“真實世界”中格式錯誤的HTML非常寬容。對象模型與System.Xml非常相似,但適用於HTML文檔或流。

NuGet安裝引用:

dotnet add package HtmlAgilityPack --version 1.11.51

二、實現核心代碼:

設計定義實體:

網站爬取信息:
image

爬取信息實體定義:根據美圖的首頁展示的信息分析,進行定義爬取欄位的信息,定義如下:

#region << 版 本 註 釋 >>
/*----------------------------------------------------------------
 * 創建者:碼農阿亮
 * 創建時間:2023/8/4 9:58:03
 * 版本:V1.0.0
 * 描述:
 *
 * ----------------------------------------------------------------
 * 修改人:
 * 時間:
 * 修改說明:
 *
 * 版本:V1.0.1
 *----------------------------------------------------------------*/
#endregion << 版 本 註 釋 >>

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;


namespace CrawlerModel.Meitu
{

    /// <summary>
    ///  爬取的專區欄位實體
    /// </summary>
    public class BeautyZone
    {

        /// <summary>
        /// 專區標題
        /// </summary>
        public string Tittle { get; set; }
        /// <summary>
        /// 專區每種類型美女排行榜
        /// </summary>
        public List<EveryCategoryBeautyTop> categoryBeauties { get; set; }

    }

    /// <summary>
    ///  每分類美女排行榜
    /// </summary>
    public class EveryCategoryBeautyTop
    {
        /// <summary>
        /// 類別
        /// </summary>
         public string Category { get; set; }
        /// <summary>
        /// 每種類型排行榜
        /// </summary>
        public List<Beauty> beauties { get; set; }
        
    }

    /// <summary>
    /// 美女排行信息
    /// </summary>
    public  class Beauty
    {
        /// <summary>
        /// 排行
        /// </summary>
        public string  No { get; set; }
        /// <summary>
        /// 姓名
        /// </summary>
        public  string Name { get; set; }
        /// <summary>
        /// 熱度
        /// </summary>
        public string  Popularity { get; set; }
        /// <summary>
        /// 圖片地址
        /// </summary>
        public string ImageUrl { get; set; }
    }
}

更新UI界面實體定義:根據客戶端需要展示的界面,定義如下:

#region << 版 本 註 釋 >>
/*----------------------------------------------------------------
 * 創建者:碼農阿亮
 * 創建時間:2023/8/04 16:42:12
 * 版本:V1.0.0
 * 描述:
 *
 * ----------------------------------------------------------------
 * 修改人:
 * 時間:
 * 修改說明:
 *
 * 版本:V1.0.1
 *----------------------------------------------------------------*/
#endregion << 版 本 註 釋 >>

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;


namespace CrawlerModel.Meitu
{
    /// <summary>
    /// UpdateUIModel 更新UI界面需要的欄位
    /// </summary>
    public class UpdateUIModel
    {
        /// <summary>
        /// 下載的數量
        /// </summary>
        public int DownloadNumber { get; set; }
        /// <summary>
        /// 分類
        /// </summary>
        public string Category { get; set; }
        /// <summary>
        /// 美女寫真實體
        /// </summary>
        public Beauty beauty =new Beauty();
        

    }
}


匹配DOM標簽常量實體: 定義如下:

#region << 版 本 註 釋 >>
/*----------------------------------------------------------------
 * 創建者:碼農阿亮
 * 創建時間:2023/8/4 10:08:06
 * 版本:V1.0.0
 * 描述:
 *
 * ----------------------------------------------------------------
 * 修改人:
 * 時間:
 * 修改說明:
 *
 * 版本:V1.0.1
 *----------------------------------------------------------------*/
#endregion << 版 本 註 釋 >>

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;


namespace CrawlerModel.Meitu
{
    /// <summary>
    /// MeituConfig DOM標簽常量
    /// </summary>
    public class MeituConfig
    {
        /// <summary>
        /// 存放數據地址
        /// </summary>
        public const string JsonDataPath = "meitu/data";
        /// <summary>
        /// 爬取美圖首頁地址
        /// </summary>
        public const string Url = "https://www.meitu131.com";
        /// <summary>
        /// 專區XPath
        /// </summary>
        public const string ZoneXPath = @"/html/body/div[10]/div[2]/div";
        /// <summary>
        /// 專區名稱XPath
        /// </summary>
        public const string ZoneNameXPath = @"/html/body/div[10]/div[1]/ul/li";
        /// <summary>
        /// 排行榜
        /// </summary>
        public const string TopXPath = @"/html/body/div[10]/div[2]/div[{0}]/dl";
        /// <summary>
        /// 人員隸屬種類
        /// </summary>
        public const string PersonCategoryXPath = @"/html/body/div[10]/div[2]/div[{0}]/dl/dt";
        /// <summary>
        /// 人員
        /// </summary>
        public const string PersonXPath = @"/html/body/div[10]/div[2]/div[{0}]/dl/dd";
        /// <summary>
        /// 排行
        /// </summary>
        public const string NoXPath = @"/html/body/div[3]/div[1]/ul/li";
        /// <summary>
        /// 姓名
        /// </summary>
        public const string NameXPath = @"/html/body/div[3]/div[1]/ul/li";
        /// <summary>
        /// 熱度
        /// </summary>
        public const string PopularityXPath = @"/html/body/div[3]/div[1]/ul/li";
        /// <summary>
        /// 圖片地址
        /// </summary>
        public const string ImageUrlXPath = @"/html/body/div[3]/div[1]/ul/li";

    }
}

業務實現代碼:

幫助類:Web請求和下載資源幫助方法,定義義如下:

#region << 版 本 註 釋 >>
/*----------------------------------------------------------------
 * 創建者:碼農阿亮
 * 創建時間:2023/8/4 10:04:16
 * 版本:V1.0.0
 * 描述:
 *
 * ----------------------------------------------------------------
 * 修改人:
 * 時間:
 * 修改說明:
 *
 * 版本:V1.0.1
 *----------------------------------------------------------------*/
#endregion << 版 本 註 釋 >>
using HtmlAgilityPack;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;

namespace CrawlerService.Helper
{

  /// <summary>
  /// 創建一個Web請求
  /// </summary>
   public class MyWebClient : WebClient
    {
        protected override WebRequest GetWebRequest(Uri address)
        {
            HttpWebRequest request = base.GetWebRequest(address) as HttpWebRequest;
            request.AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip;
            return request;
        }
    }
    /// <summary>
    /// 下載HTML幫助類
    /// </summary>
    public static class LoadHtmlHelper
    {
        /// <summary>
        /// 從Url地址下載頁面
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        public async static ValueTask<HtmlDocument> LoadHtmlFromUrlAsync(string url)
        {
            var data = new MyWebClient()?.DownloadString(url);
            var doc = new HtmlDocument();
            doc.LoadHtml(data);
            return doc;
        }

        /// <summary>
        /// 獲取單個節點擴展方法
        /// </summary>
        /// <param name="htmlDocument">文檔對象</param>
        /// <param name="xPath">xPath路徑</param>
        /// <returns></returns>
        public static HtmlNode GetSingleNode(this HtmlDocument htmlDocument, string xPath)
        {
          return  htmlDocument?.DocumentNode?.SelectSingleNode(xPath);
        }

        /// <summary>
        /// 獲取多個節點擴展方法
        /// </summary>
        /// <param name="htmlDocument">文檔對象</param>
        /// <param name="xPath">xPath路徑</param>
        /// <returns></returns>
        public static HtmlNodeCollection GetNodes(this HtmlDocument htmlDocument, string xPath)
        {
            return htmlDocument?.DocumentNode?.SelectNodes(xPath);
        }

     

        /// <summary>
        /// 獲取多個節點擴展方法
        /// </summary>
        /// <param name="htmlDocument">文檔對象</param>
        /// <param name="xPath">xPath路徑</param>
        /// <returns></returns>
        public static HtmlNodeCollection GetNodes(this HtmlNode htmlNode, string xPath)
        {
            return htmlNode?.SelectNodes(xPath);
        }


        /// <summary>
        /// 獲取單個節點擴展方法
        /// </summary>
        /// <param name="htmlDocument">文檔對象</param>
        /// <param name="xPath">xPath路徑</param>
        /// <returns></returns>
        public static HtmlNode GetSingleNode(this HtmlNode htmlNode, string xPath)
        {
            return htmlNode?.SelectSingleNode(xPath);
        }

        /// <summary>
        /// 下載圖片
        /// </summary>
        /// <param name="url">地址</param>
        /// <param name="filpath">文件路徑</param>
        /// <returns></returns>
        public async static ValueTask<bool> DownloadImg(string url ,string filpath)
        {
            HttpClient httpClient = new HttpClient();
            try
            {
                var bytes = await httpClient.GetByteArrayAsync(url);
                using (FileStream fs = File.Create(filpath))
                {
                    fs.Write(bytes, 0, bytes.Length);
                }
                return File.Exists(filpath);
            }
            catch (Exception ex)
            {
             
                throw new Exception("下載圖片異常", ex);
            }
            
        }
    }
}

主要業務實現方法:定義如下:

#region << 版 本 註 釋 >>
/*----------------------------------------------------------------
 * 創建者:碼農阿亮
 * 創建時間:2023/8/4 10:07:17
 * 版本:V1.0.0
 * 描述:
 *
 * ----------------------------------------------------------------
 * 修改人:
 * 時間:
 * 修改說明:
 *
 * 版本:V1.0.1
 *----------------------------------------------------------------*/
#endregion << 版 本 註 釋 >>

using CrawlerComm.Handler;
using CrawlerModel.Meitu;
using CrawlerService.Helper;
using HtmlAgilityPack;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;


namespace CrawlerService.Meitu
{
    /// <summary>
    /// MeituParseHtml 的摘要說明
    /// </summary>
    public class MeituParseHtmService
    {

        /// <summary>
        /// json數據文件夾存放文件夾位置
        /// </summary>
        private static string _dataDirectoryPath = Path.Combine(Directory.GetCurrentDirectory(), MeituConfig.JsonDataPath);

        /// <summary>
        /// 爬取json數據文件 
        /// </summary>
        private static string _CrawlerData = Path.Combine(_dataDirectoryPath, "categories.json");

        /// <summary>
        /// 開始爬取
        /// </summary>
        /// <returns></returns>
        public async Task StartAsync()
        {
            //專區集合
            List<BeautyZone> beautyZones = new List<BeautyZone>();
            //獲取首頁Html文檔
            HtmlDocument htmlDocument = await LoadHtmlHelper.LoadHtmlFromUrlAsync(MeituConfig.Url);

            //創建存放數據的文件
            FileInfo fileInfo = new FileInfo(_CrawlerData);

            //獲取到專區標簽
            HtmlNodeCollection zoneHtmlNodes = htmlDocument.GetNodes(MeituConfig.ZoneXPath);
            //專區名稱
            HtmlNodeCollection zoneNameHtmlNodes = htmlDocument.GetNodes(MeituConfig.ZoneNameXPath);

            if (zoneHtmlNodes != null && zoneHtmlNodes.Count> 0)
            {
                //專區個數
                var zoneCount = zoneHtmlNodes.Count;
                for (int i = 0; i < zoneCount; i++)
                {
                    //每個專區
                    BeautyZone beautyZone = new BeautyZone()
                    {
                        Tittle = zoneNameHtmlNodes[i].InnerText,
                        categoryBeauties = new List<EveryCategoryBeautyTop>()
                    };

                    HtmlNodeCollection topHtmlNodes = htmlDocument.GetNodes(string.Format( MeituConfig.TopXPath,i+1));
                    if (topHtmlNodes != null && topHtmlNodes.Count > 0)
                    {
                        //每個專區下所有分類
                        HtmlNodeCollection personCategoryHtmlNodes = htmlDocument.GetNodes(string.Format(MeituConfig.PersonCategoryXPath, i + 1));
                        //爬取所有人員的標簽內容
                        HtmlNodeCollection personHtmlNodes = htmlDocument.GetNodes(string.Format(MeituConfig.PersonXPath, i + 1));

                        if (personCategoryHtmlNodes !=null && personHtmlNodes!=null  && personCategoryHtmlNodes.Count() > 0)
                        {

                            for (int j = 0; j < personCategoryHtmlNodes.Count(); j++)
                            {
                                //根據每個專區-分類下,進行遍歷人氣值人員排名
                                EveryCategoryBeautyTop everyCategoryBeautyTop = new EveryCategoryBeautyTop();
                                everyCategoryBeautyTop.Category = personCategoryHtmlNodes[j].InnerText;
                                everyCategoryBeautyTop.beauties = new List<Beauty>();
                                for (int k = 8*j; k < personHtmlNodes.Count(); k++)
                                {
                                    var child = personHtmlNodes[k];//每個美女對應的節點信息

                                    var i1 = child.GetSingleNode(child.XPath + "/i");//排名節點
                                    var img = child.GetSingleNode(child.XPath + "/a[1]/div[1]/img[1]");//姓名和圖片地址
                                    var span2 = child.GetSingleNode(child.XPath + "/a[1]/div[2]/span[2]");//熱度值
                                    //同一類別添加美女到集合
                                    everyCategoryBeautyTop.beauties.Add(new Beauty
                                    {
                                        No = i1.InnerText,
                                        Name = img.GetAttributeValue("alt", "未找到"),
                                        Popularity = span2.InnerText,
                                        ImageUrl = img.GetAttributeValue("data-echo", "未找到")
                                    }
                                    );
                                }
                                //將在同一分區內Top分類添加到集合
                                beautyZone.categoryBeauties.Add(everyCategoryBeautyTop);
                            }
                                    
                        }
                       
                    }
                    beautyZones.Add(beautyZone);
                }
                if (beautyZones.Count()> 0)
                {
                    //爬取數據轉Json
                    string beautiesJsonData = JsonConvert.SerializeObject(beautyZones); ;
                    //寫入爬取數據數據
                    string jsonFile = "beauties.json";
                    WriteData(jsonFile, beautiesJsonData);
                    //下載圖片
                    DownloadImage(beautyZones);

                }
            }
        }

        /// <summary>
        /// 寫入文件數據
        /// </summary>
        /// <param name="fileName"></param>
        /// <param name="data"></param>
        private void WriteData(string fileName, string data)
        {

            FileStream fs = new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.Write);
            StreamWriter sw = new StreamWriter(fs);
            try
            {
                sw.Write(data);
            }
            finally
            {
                if (sw != null)
                {
                    sw.Close();
                }
            }
        }
 
        /// <summary>
        /// 下載圖片
        /// </summary>
        /// <param name="beautyZones"></param>
        private async void DownloadImage(List<BeautyZone> beautyZones)
        {
            int count = 0;
            foreach (var beautyZone in beautyZones)
            {
                string rootPath =  System.IO.Directory.GetCurrentDirectory() +"\\DownloadImg\\"+ beautyZone.Tittle;
                foreach (var category in beautyZone.categoryBeauties)
                {
                   string downloadPath = rootPath + "\\" + category.Category;
                    foreach (var beauty in category.beauties)
                    {
                        count += 1;//下載數量累加
                        string filePath = downloadPath + "\\" + beauty.Name+".jpg";
                        if (!Directory.Exists(downloadPath))
                        {
                            Directory.CreateDirectory(downloadPath);
                        }
                        UpdateUIModel updateUIModel = new UpdateUIModel()
                        {
                            DownloadNumber =count,
                            Category = category.Category,
                            beauty = beauty

                        };
                        //更新UI
                        UpdateFrmHandler.OnUpdateUI(updateUIModel);
                        //非同步下載
                        await  LoadHtmlHelper.DownloadImg(beauty.ImageUrl,filePath);
                    }
                }
            }
        }
    }
}

定義委托代碼:

更新UI界面的委托事件:定義如下:

#region << 版 本 註 釋 >>
/*----------------------------------------------------------------
 * 創建者:碼農阿亮
 * 創建時間:2023/8/04 11:28:24
 * 版本:V1.0.0
 * 描述:
 *
 * ----------------------------------------------------------------
 * 修改人:
 * 時間:
 * 修改說明:
 *
 * 版本:V1.0.1
 *----------------------------------------------------------------*/
#endregion << 版 本 註 釋 >>

using CrawlerModel.Meitu;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;


namespace CrawlerComm.Handler
{
    /// <summary>
    /// UpdateFrmHandler 更新UI事件委托
    /// </summary>
    public class UpdateFrmHandler
    {
        /// <summary>
        /// 更新下載界面事件
        /// </summary>
        public static event EventHandler<UpdateUIModel> UpdateUI;
        public static void OnUpdateUI(UpdateUIModel updateUIModel)
        {
            UpdateUI?.Invoke(null, updateUIModel);
        }
    }
}

客戶端執行代碼:

點擊觸發事件:定義如下:

#region << 版 本 註 釋 >>
/*----------------------------------------------------------------
 * 創建者:碼農阿亮
 * 創建時間:2023/8/4 08:07:17
 * 版本:V1.0.0
 * 描述:
 *
 * ----------------------------------------------------------------
 * 修改人:
 * 時間:
 * 修改說明:
 *
 * 版本:V1.0.1
 *----------------------------------------------------------------*/
#endregion << 版 本 註 釋 >>
using CrawlerComm.Handler;
using CrawlerModel.Meitu;
using CrawlerService.Meitu;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace CrawlerData
{
    public partial class FrmMain : Form
    {
        public FrmMain()
        {
            InitializeComponent();
            //訂閱委托
            UpdateFrmHandler.UpdateUI += UpdateUIFuc;
        }

        /// <summary>
        /// 更新界面委托方法
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="updateUIModel"></param>
        private void UpdateUIFuc(object sender, UpdateUIModel updateUIModel )
        {
            try
            {

                //改變界面UI中的值
                this.Invoke((Action)delegate
                {
                    UpdateUIBiz(updateUIModel);
                });

            }
            catch (Exception ex)
            {
              
            }
        }
        /// <summary>
        /// 更新UI界面業務
        /// </summary>
        /// <param name="updateUIModel"></param>
        private void UpdateUIBiz(UpdateUIModel updateUIModel)
        {
            try
            {
                //分類
                tbCategory.Text = updateUIModel.Category;
                //排名
                tbNo.Text = updateUIModel.beauty.No;
                //姓名
                tbName.Text = updateUIModel.beauty.Name;
                //人氣值
                tbPopularity.Text = updateUIModel.beauty.Popularity;
                //圖片地址
                tbUrl.Text = updateUIModel.beauty.ImageUrl;
                //圖片
                WebClient client = new WebClient();
                string imageUrl = updateUIModel.beauty.ImageUrl;// 要顯示的網路圖片的URL
                byte[] imageBytes = client.DownloadData(imageUrl);
                Image img = Image.FromStream(new MemoryStream(imageBytes));
                picBox.Image = img;
                //爬取數量
                lbNumber.Text = updateUIModel.DownloadNumber.ToString();
                
            }
            catch (Exception ex)
            {

            }
        }
        /// <summary>
        /// 開始執行按鈕點擊事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private  void btStart_Click(object sender, EventArgs e)
        {
            StartCrawler();
        }

        /// <summary>
        /// 開始爬取
        /// </summary>
        public async void StartCrawler()
        {
            try
            {
                MeituParseHtmService meituParseHtml = new MeituParseHtmService();
                await meituParseHtml.StartAsync();
            }
            catch (Exception ex )
            {

            }
        
        }
    }
}

三、爬取驗證:

啟動客戶端:

文章上傳圖片大小有限制,只截取了部分gif:

image

爬取的Json數據結果:

image

下載的圖片資源:

分目錄層級存放:
image

源碼鏈接地址:

Gitee完整實例地址:

https://gitee.com/mingliang_it/CrawlerDataClient

建群聲明:本著技術在於分享,方便大家交流學習的初心,特此建立【編程內功修煉交流群】,熱烈歡迎各位愛交流學習的程式員進群,也希望進群的大佬能不吝分享自己遇到的技術問題和學習心得

image

本文來自博客園,作者:碼農阿亮,轉載請註明原文鏈接:https://www.cnblogs.com/wml-it/p/17628041.html


技術的發展日新月異,隨著時間推移,無法保證本博客所有內容的正確性。如有誤導,請大家見諒,歡迎評論區指正!
開源庫鏈接,歡迎點亮:
GitHub:https://github.com/ITMingliang
Gitee:https://gitee.com/mingliang_it
GitLab:https://gitlab.com/ITMingliang
【編程內功修煉交流群】:                       【個人公眾號】:
           

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • SpringSecurity組件可以為服務提供安全管理的能力,比如身份驗證、授權和針對常見攻擊的保護,是保護基於spring應用程式的事實上的標準; ...
  • 本文將從一個服務註冊示例入手,通過閱讀客戶端、服務端源碼,分析服務註冊、服務發現原理。 使用的2.0.2的版本。 # 客戶端 ## 創建NacosNamingService對象 ```java NacosNamingService nacosNamingService = new NacosNami ...
  • ## 教程簡介 Maven 是一款基於 Java 平臺的項目管理和整合工具,它將項目的開發和管理過程抽象成一個項目對象模型(POM)。開發人員只需要做一些簡單的配置,Maven 就可以自動完成項目的編譯、測試、打包、發佈以及部署等工作。Maven 是使用 Java 語言編寫的,因此它和 Java 一 ...
  • # 數據安全之資料庫欄位加解密檢索和前端返回脫敏?看看我這個最強解決方案 ## 前言 數據安全一直是我們老生常談的話題了,隨著國產化的日漸推進和數字化信息改革,數據安全越來越被人們所重視。資料庫作為存儲、管理和檢索數據的核心基礎設施,其中可能包含著大量的敏感信息,如個人手機號、身份證號碼、銀行賬戶、 ...
  • TPTABP採用ABP6.0微服務架構。TPTABP擁有更強大的許可權系統,許可權可控制到按鈕、api級別。ABP本身使用多租戶、模塊化、領域驅動設計、微服務等架構設計, 支持多個ORM切換,支持後臺任務(HangFire,Quartz)集成、 事件匯流排、AutoMapper、審計日誌、數據過濾等基礎設 ...
  • 在項目中有的時候可能會用的畫虛線或者設置線的流動效果,這個時候可能會使用到線控制項。 屬性 說明 描述 X1 起始x軸坐標 X1="10" Y1 起始Y軸坐標 Y1="10" X2 結束X軸坐標 X2="100" Y2 結束Y軸坐標 Y2="100" Stroke 線條顏色 Stroke="Red" ...
  • 開源的git管理工具確實非常方便,相信很多小伙伴工作了一些年都會有自己的代碼庫,有的時候做一個新的項目了,需要使用到以前用過的技術,這個時候在去翻找以前的項目,可能就找不到了,但是吧代碼庫都整理到git上就方便多了,而且有什麼新的代碼或者優化等等都可以在任何地方修改和同步,想想還是很厲害的。 下載安 ...
  • 作為.NET開發者,介面是C#必須掌握的知識點,介面是C#中實現多態和組件間互操作性的關鍵機制之一。 介面是一種抽象的類型,它定義了一組成員(方法、屬性、事件等)的規範,但沒有實現代碼。類可以實現一個或多個介面,以表明它們提供了特定的功能。 以下是每個.NET開發者應該掌握的C#介面知識點: **1 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...