翼度科技»论坛 编程开发 .net 查看内容

.NET爬取美图官网首页数据实战

7

主题

7

帖子

21

积分

新手上路

Rank: 1

积分
21
前言:

  在当今信息化社会,网络数据分析越来越受到重视。而作为开发人员,掌握一门能够抓取网页内容的语言显得尤为重要。在此篇文章中,将分享如何使用 .NET构建网络抓取工具。详细了解如何执行 HTTP 请求来下载要抓取的网页,然后从其 DOM 树中选择 HTML 元素,进行匹配需要的字段信息,从中提取数据。
一、准备工作:

创建项目:

​    创建一个简单的Winfrom客户端程序,我使用的是.NET 5.0框架。为使项目显得条理清晰,此处进行了项目分层搭建项目,也就是多建立几个几个类库罢了,然后进行引用。
项目结构:

客户端界面设计:

NuGet添加引用类库HtmlAgilityPack:

​    HtmlAgilityPack是一个开源的C#库,它允许你解析HTML文档,从公DOM中选择元素并提取数据。该工具基本上提供了抓取静态内容网站所需要的一切。这是一个敏捷的HTML解析器,它构建了一个读和写DOM,并支持普通的XPATH或XSLT,你实际上不必了解XPATH也不必了解XSLT就可以使用它。它是一个.NET代码库,允许你解析“Web外”的HTML文件。解析器对“真实世界”中格式错误的HTML非常宽容。对象模型与System.Xml非常相似,但适用于HTML文档或流。
NuGet安装引用:


  1. dotnet add package HtmlAgilityPack --version 1.11.51
复制代码
二、实现核心代码:

设计定义实体:

网站爬取信息:

爬取信息实体定义:根据美图的首页展示的信息分析,进行定义爬取字段的信息,定义如下:
  1. #region << 版 本 注 释 >>
  2. /*----------------------------------------------------------------
  3. * 创建者:码农阿亮
  4. * 创建时间:2023/8/4 9:58:03
  5. * 版本:V1.0.0
  6. * 描述:
  7. *
  8. * ----------------------------------------------------------------
  9. * 修改人:
  10. * 时间:
  11. * 修改说明:
  12. *
  13. * 版本:V1.0.1
  14. *----------------------------------------------------------------*/
  15. #endregion << 版 本 注 释 >>
  16. using System;
  17. using System.Collections.Generic;
  18. using System.Linq;
  19. using System.Text;
  20. using System.Threading.Tasks;
  21. namespace CrawlerModel.Meitu
  22. {
  23.     /// <summary>
  24.     ///  爬取的专区字段实体
  25.     /// </summary>
  26.     public class BeautyZone
  27.     {
  28.         /// <summary>
  29.         /// 专区标题
  30.         /// </summary>
  31.         public string Tittle { get; set; }
  32.         /// <summary>
  33.         /// 专区每种类型美女排行榜
  34.         /// </summary>
  35.         public List<EveryCategoryBeautyTop> categoryBeauties { get; set; }
  36.     }
  37.     /// <summary>
  38.     ///  每分类美女排行榜
  39.     /// </summary>
  40.     public class EveryCategoryBeautyTop
  41.     {
  42.         /// <summary>
  43.         /// 类别
  44.         /// </summary>
  45.          public string Category { get; set; }
  46.         /// <summary>
  47.         /// 每种类型排行榜
  48.         /// </summary>
  49.         public List<Beauty> beauties { get; set; }
  50.         
  51.     }
  52.     /// <summary>
  53.     /// 美女排行信息
  54.     /// </summary>
  55.     public  class Beauty
  56.     {
  57.         /// <summary>
  58.         /// 排行
  59.         /// </summary>
  60.         public string  No { get; set; }
  61.         /// <summary>
  62.         /// 姓名
  63.         /// </summary>
  64.         public  string Name { get; set; }
  65.         /// <summary>
  66.         /// 热度
  67.         /// </summary>
  68.         public string  Popularity { get; set; }
  69.         /// <summary>
  70.         /// 图片地址
  71.         /// </summary>
  72.         public string ImageUrl { get; set; }
  73.     }
  74. }
复制代码
更新UI界面实体定义:根据客户端需要展示的界面,定义如下:
  1. #region << 版 本 注 释 >>
  2. /*----------------------------------------------------------------
  3. * 创建者:码农阿亮
  4. * 创建时间:2023/8/04 16:42:12
  5. * 版本:V1.0.0
  6. * 描述:
  7. *
  8. * ----------------------------------------------------------------
  9. * 修改人:
  10. * 时间:
  11. * 修改说明:
  12. *
  13. * 版本:V1.0.1
  14. *----------------------------------------------------------------*/
  15. #endregion << 版 本 注 释 >>
  16. using System;
  17. using System.Collections.Generic;
  18. using System.Linq;
  19. using System.Text;
  20. using System.Threading.Tasks;
  21. namespace CrawlerModel.Meitu
  22. {
  23.     /// <summary>
  24.     /// UpdateUIModel 更新UI界面需要的字段
  25.     /// </summary>
  26.     public class UpdateUIModel
  27.     {
  28.         /// <summary>
  29.         /// 下载的数量
  30.         /// </summary>
  31.         public int DownloadNumber { get; set; }
  32.         /// <summary>
  33.         /// 分类
  34.         /// </summary>
  35.         public string Category { get; set; }
  36.         /// <summary>
  37.         /// 美女写真实体
  38.         /// </summary>
  39.         public Beauty beauty =new Beauty();
  40.         
  41.     }
  42. }
复制代码
匹配DOM标签常量实体: 定义如下:
  1. #region << 版 本 注 释 >>
  2. /*----------------------------------------------------------------
  3. * 创建者:码农阿亮
  4. * 创建时间:2023/8/4 10:08:06
  5. * 版本:V1.0.0
  6. * 描述:
  7. *
  8. * ----------------------------------------------------------------
  9. * 修改人:
  10. * 时间:
  11. * 修改说明:
  12. *
  13. * 版本:V1.0.1
  14. *----------------------------------------------------------------*/
  15. #endregion << 版 本 注 释 >>
  16. using System;
  17. using System.Collections.Generic;
  18. using System.Linq;
  19. using System.Text;
  20. using System.Threading.Tasks;
  21. namespace CrawlerModel.Meitu
  22. {
  23.     /// <summary>
  24.     /// MeituConfig DOM标签常量
  25.     /// </summary>
  26.     public class MeituConfig
  27.     {
  28.         /// <summary>
  29.         /// 存放数据地址
  30.         /// </summary>
  31.         public const string JsonDataPath = "meitu/data";
  32.         /// <summary>
  33.         /// 爬取美图首页地址
  34.         /// </summary>
  35.         public const string Url = "https://www.meitu131.com";
  36.         /// <summary>
  37.         /// 专区XPath
  38.         /// </summary>
  39.         public const string ZoneXPath = @"/html/body/div[10]/div[2]/div";
  40.         /// <summary>
  41.         /// 专区名称XPath
  42.         /// </summary>
  43.         public const string ZoneNameXPath = @"/html/body/div[10]/div[1]/ul/li";
  44.         /// <summary>
  45.         /// 排行榜
  46.         /// </summary>
  47.         public const string TopXPath = @"/html/body/div[10]/div[2]/div[{0}]/dl";
  48.         /// <summary>
  49.         /// 人员隶属种类
  50.         /// </summary>
  51.         public const string PersonCategoryXPath = @"/html/body/div[10]/div[2]/div[{0}]/dl/dt";
  52.         /// <summary>
  53.         /// 人员
  54.         /// </summary>
  55.         public const string PersonXPath = @"/html/body/div[10]/div[2]/div[{0}]/dl/dd";
  56.         /// <summary>
  57.         /// 排行
  58.         /// </summary>
  59.         public const string NoXPath = @"/html/body/div[3]/div[1]/ul/li";
  60.         /// <summary>
  61.         /// 姓名
  62.         /// </summary>
  63.         public const string NameXPath = @"/html/body/div[3]/div[1]/ul/li";
  64.         /// <summary>
  65.         /// 热度
  66.         /// </summary>
  67.         public const string PopularityXPath = @"/html/body/div[3]/div[1]/ul/li";
  68.         /// <summary>
  69.         /// 图片地址
  70.         /// </summary>
  71.         public const string ImageUrlXPath = @"/html/body/div[3]/div[1]/ul/li";
  72.     }
  73. }
复制代码
业务实现代码:

帮助类:Web请求和下载资源帮助方法,定义义如下:
  1. #region << 版 本 注 释 >>
  2. /*----------------------------------------------------------------
  3. * 创建者:码农阿亮
  4. * 创建时间:2023/8/4 10:04:16
  5. * 版本:V1.0.0
  6. * 描述:
  7. *
  8. * ----------------------------------------------------------------
  9. * 修改人:
  10. * 时间:
  11. * 修改说明:
  12. *
  13. * 版本:V1.0.1
  14. *----------------------------------------------------------------*/
  15. #endregion << 版 本 注 释 >>
  16. using HtmlAgilityPack;
  17. using System;
  18. using System.Collections.Generic;
  19. using System.IO;
  20. using System.Linq;
  21. using System.Net;
  22. using System.Net.Http;
  23. using System.Text;
  24. using System.Threading.Tasks;
  25. namespace CrawlerService.Helper
  26. {
  27.   /// <summary>
  28.   /// 创建一个Web请求
  29.   /// </summary>
  30.    public class MyWebClient : WebClient
  31.     {
  32.         protected override WebRequest GetWebRequest(Uri address)
  33.         {
  34.             HttpWebRequest request = base.GetWebRequest(address) as HttpWebRequest;
  35.             request.AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip;
  36.             return request;
  37.         }
  38.     }
  39.     /// <summary>
  40.     /// 下载HTML帮助类
  41.     /// </summary>
  42.     public static class LoadHtmlHelper
  43.     {
  44.         /// <summary>
  45.         /// 从Url地址下载页面
  46.         /// </summary>
  47.         /// <param name="url"></param>
  48.         /// <returns></returns>
  49.         public async static ValueTask<HtmlDocument> LoadHtmlFromUrlAsync(string url)
  50.         {
  51.             var data = new MyWebClient()?.DownloadString(url);
  52.             var doc = new HtmlDocument();
  53.             doc.LoadHtml(data);
  54.             return doc;
  55.         }
  56.         /// <summary>
  57.         /// 获取单个节点扩展方法
  58.         /// </summary>
  59.         /// <param name="htmlDocument">文档对象</param>
  60.         /// <param name="xPath">xPath路径</param>
  61.         /// <returns></returns>
  62.         public static HtmlNode GetSingleNode(this HtmlDocument htmlDocument, string xPath)
  63.         {
  64.           return  htmlDocument?.DocumentNode?.SelectSingleNode(xPath);
  65.         }
  66.         /// <summary>
  67.         /// 获取多个节点扩展方法
  68.         /// </summary>
  69.         /// <param name="htmlDocument">文档对象</param>
  70.         /// <param name="xPath">xPath路径</param>
  71.         /// <returns></returns>
  72.         public static HtmlNodeCollection GetNodes(this HtmlDocument htmlDocument, string xPath)
  73.         {
  74.             return htmlDocument?.DocumentNode?.SelectNodes(xPath);
  75.         }
  76.      
  77.         /// <summary>
  78.         /// 获取多个节点扩展方法
  79.         /// </summary>
  80.         /// <param name="htmlDocument">文档对象</param>
  81.         /// <param name="xPath">xPath路径</param>
  82.         /// <returns></returns>
  83.         public static HtmlNodeCollection GetNodes(this HtmlNode htmlNode, string xPath)
  84.         {
  85.             return htmlNode?.SelectNodes(xPath);
  86.         }
  87.         /// <summary>
  88.         /// 获取单个节点扩展方法
  89.         /// </summary>
  90.         /// <param name="htmlDocument">文档对象</param>
  91.         /// <param name="xPath">xPath路径</param>
  92.         /// <returns></returns>
  93.         public static HtmlNode GetSingleNode(this HtmlNode htmlNode, string xPath)
  94.         {
  95.             return htmlNode?.SelectSingleNode(xPath);
  96.         }
  97.         /// <summary>
  98.         /// 下载图片
  99.         /// </summary>
  100.         /// <param name="url">地址</param>
  101.         /// <param name="filpath">文件路径</param>
  102.         /// <returns></returns>
  103.         public async static ValueTask<bool> DownloadImg(string url ,string filpath)
  104.         {
  105.             HttpClient httpClient = new HttpClient();
  106.             try
  107.             {
  108.                 var bytes = await httpClient.GetByteArrayAsync(url);
  109.                 using (FileStream fs = File.Create(filpath))
  110.                 {
  111.                     fs.Write(bytes, 0, bytes.Length);
  112.                 }
  113.                 return File.Exists(filpath);
  114.             }
  115.             catch (Exception ex)
  116.             {
  117.             
  118.                 throw new Exception("下载图片异常", ex);
  119.             }
  120.             
  121.         }
  122.     }
  123. }
复制代码
主要业务实现方法:定义如下:
  1. #region << 版 本 注 释 >>
  2. /*----------------------------------------------------------------
  3. * 创建者:码农阿亮
  4. * 创建时间:2023/8/4 10:07:17
  5. * 版本:V1.0.0
  6. * 描述:
  7. *
  8. * ----------------------------------------------------------------
  9. * 修改人:
  10. * 时间:
  11. * 修改说明:
  12. *
  13. * 版本:V1.0.1
  14. *----------------------------------------------------------------*/
  15. #endregion << 版 本 注 释 >>
  16. using CrawlerComm.Handler;
  17. using CrawlerModel.Meitu;
  18. using CrawlerService.Helper;
  19. using HtmlAgilityPack;
  20. using Newtonsoft.Json;
  21. using System;
  22. using System.Collections.Generic;
  23. using System.IO;
  24. using System.Linq;
  25. using System.Text;
  26. using System.Threading.Tasks;
  27. namespace CrawlerService.Meitu
  28. {
  29.     /// <summary>
  30.     /// MeituParseHtml 的摘要说明
  31.     /// </summary>
  32.     public class MeituParseHtmService
  33.     {
  34.         /// <summary>
  35.         /// json数据文件夹存放文件夹位置
  36.         /// </summary>
  37.         private static string _dataDirectoryPath = Path.Combine(Directory.GetCurrentDirectory(), MeituConfig.JsonDataPath);
  38.         /// <summary>
  39.         /// 爬取json数据文件
  40.         /// </summary>
  41.         private static string _CrawlerData = Path.Combine(_dataDirectoryPath, "categories.json");
  42.         /// <summary>
  43.         /// 开始爬取
  44.         /// </summary>
  45.         /// <returns></returns>
  46.         public async Task StartAsync()
  47.         {
  48.             //专区集合
  49.             List<BeautyZone> beautyZones = new List<BeautyZone>();
  50.             //获取首页Html文档
  51.             HtmlDocument htmlDocument = await LoadHtmlHelper.LoadHtmlFromUrlAsync(MeituConfig.Url);
  52.             //创建存放数据的文件
  53.             FileInfo fileInfo = new FileInfo(_CrawlerData);
  54.             //获取到专区标签
  55.             HtmlNodeCollection zoneHtmlNodes = htmlDocument.GetNodes(MeituConfig.ZoneXPath);
  56.             //专区名称
  57.             HtmlNodeCollection zoneNameHtmlNodes = htmlDocument.GetNodes(MeituConfig.ZoneNameXPath);
  58.             if (zoneHtmlNodes != null && zoneHtmlNodes.Count> 0)
  59.             {
  60.                 //专区个数
  61.                 var zoneCount = zoneHtmlNodes.Count;
  62.                 for (int i = 0; i < zoneCount; i++)
  63.                 {
  64.                     //每个专区
  65.                     BeautyZone beautyZone = new BeautyZone()
  66.                     {
  67.                         Tittle = zoneNameHtmlNodes[i].InnerText,
  68.                         categoryBeauties = new List<EveryCategoryBeautyTop>()
  69.                     };
  70.                     HtmlNodeCollection topHtmlNodes = htmlDocument.GetNodes(string.Format( MeituConfig.TopXPath,i+1));
  71.                     if (topHtmlNodes != null && topHtmlNodes.Count > 0)
  72.                     {
  73.                         //每个专区下所有分类
  74.                         HtmlNodeCollection personCategoryHtmlNodes = htmlDocument.GetNodes(string.Format(MeituConfig.PersonCategoryXPath, i + 1));
  75.                         //爬取所有人员的标签内容
  76.                         HtmlNodeCollection personHtmlNodes = htmlDocument.GetNodes(string.Format(MeituConfig.PersonXPath, i + 1));
  77.                         if (personCategoryHtmlNodes !=null && personHtmlNodes!=null  && personCategoryHtmlNodes.Count() > 0)
  78.                         {
  79.                             for (int j = 0; j < personCategoryHtmlNodes.Count(); j++)
  80.                             {
  81.                                 //根据每个专区-分类下,进行遍历人气值人员排名
  82.                                 EveryCategoryBeautyTop everyCategoryBeautyTop = new EveryCategoryBeautyTop();
  83.                                 everyCategoryBeautyTop.Category = personCategoryHtmlNodes[j].InnerText;
  84.                                 everyCategoryBeautyTop.beauties = new List<Beauty>();
  85.                                 for (int k = 8*j; k < personHtmlNodes.Count(); k++)
  86.                                 {
  87.                                     var child = personHtmlNodes[k];//每个美女对应的节点信息
  88.                                     var i1 = child.GetSingleNode(child.XPath + "/i");//排名节点
  89.                                     var img = child.GetSingleNode(child.XPath + "/a[1]/div[1]/img[1]");//姓名和图片地址
  90.                                     var span2 = child.GetSingleNode(child.XPath + "/a[1]/div[2]/span[2]");//热度值
  91.                                     //同一类别添加美女到集合
  92.                                     everyCategoryBeautyTop.beauties.Add(new Beauty
  93.                                     {
  94.                                         No = i1.InnerText,
  95.                                         Name = img.GetAttributeValue("alt", "未找到"),
  96.                                         Popularity = span2.InnerText,
  97.                                         ImageUrl = img.GetAttributeValue("data-echo", "未找到")
  98.                                     }
  99.                                     );
  100.                                 }
  101.                                 //将在同一分区内Top分类添加到集合
  102.                                 beautyZone.categoryBeauties.Add(everyCategoryBeautyTop);
  103.                             }
  104.                                     
  105.                         }
  106.                        
  107.                     }
  108.                     beautyZones.Add(beautyZone);
  109.                 }
  110.                 if (beautyZones.Count()> 0)
  111.                 {
  112.                     //爬取数据转Json
  113.                     string beautiesJsonData = JsonConvert.SerializeObject(beautyZones); ;
  114.                     //写入爬取数据数据
  115.                     string jsonFile = "beauties.json";
  116.                     WriteData(jsonFile, beautiesJsonData);
  117.                     //下载图片
  118.                     DownloadImage(beautyZones);
  119.                 }
  120.             }
  121.         }
  122.         /// <summary>
  123.         /// 写入文件数据
  124.         /// </summary>
  125.         /// <param name="fileName"></param>
  126.         /// <param name="data"></param>
  127.         private void WriteData(string fileName, string data)
  128.         {
  129.             FileStream fs = new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.Write);
  130.             StreamWriter sw = new StreamWriter(fs);
  131.             try
  132.             {
  133.                 sw.Write(data);
  134.             }
  135.             finally
  136.             {
  137.                 if (sw != null)
  138.                 {
  139.                     sw.Close();
  140.                 }
  141.             }
  142.         }
  143.         /// <summary>
  144.         /// 下载图片
  145.         /// </summary>
  146.         /// <param name="beautyZones"></param>
  147.         private async void DownloadImage(List<BeautyZone> beautyZones)
  148.         {
  149.             int count = 0;
  150.             foreach (var beautyZone in beautyZones)
  151.             {
  152.                 string rootPath =  System.IO.Directory.GetCurrentDirectory() +"\\DownloadImg\"+ beautyZone.Tittle;
  153.                 foreach (var category in beautyZone.categoryBeauties)
  154.                 {
  155.                    string downloadPath = rootPath + "\" + category.Category;
  156.                     foreach (var beauty in category.beauties)
  157.                     {
  158.                         count += 1;//下载数量累加
  159.                         string filePath = downloadPath + "\" + beauty.Name+".jpg";
  160.                         if (!Directory.Exists(downloadPath))
  161.                         {
  162.                             Directory.CreateDirectory(downloadPath);
  163.                         }
  164.                         UpdateUIModel updateUIModel = new UpdateUIModel()
  165.                         {
  166.                             DownloadNumber =count,
  167.                             Category = category.Category,
  168.                             beauty = beauty
  169.                         };
  170.                         //更新UI
  171.                         UpdateFrmHandler.OnUpdateUI(updateUIModel);
  172.                         //异步下载
  173.                         await  LoadHtmlHelper.DownloadImg(beauty.ImageUrl,filePath);
  174.                     }
  175.                 }
  176.             }
  177.         }
  178.     }
  179. }
复制代码
定义委托代码:

更新UI界面的委托事件:定义如下:
  1. #region << 版 本 注 释 >>
  2. /*----------------------------------------------------------------
  3. * 创建者:码农阿亮
  4. * 创建时间:2023/8/04 11:28:24
  5. * 版本:V1.0.0
  6. * 描述:
  7. *
  8. * ----------------------------------------------------------------
  9. * 修改人:
  10. * 时间:
  11. * 修改说明:
  12. *
  13. * 版本:V1.0.1
  14. *----------------------------------------------------------------*/
  15. #endregion << 版 本 注 释 >>
  16. using CrawlerModel.Meitu;
  17. using System;
  18. using System.Collections.Generic;
  19. using System.Linq;
  20. using System.Text;
  21. using System.Threading.Tasks;
  22. namespace CrawlerComm.Handler
  23. {
  24.     /// <summary>
  25.     /// UpdateFrmHandler 更新UI事件委托
  26.     /// </summary>
  27.     public class UpdateFrmHandler
  28.     {
  29.         /// <summary>
  30.         /// 更新下载界面事件
  31.         /// </summary>
  32.         public static event EventHandler<UpdateUIModel> UpdateUI;
  33.         public static void OnUpdateUI(UpdateUIModel updateUIModel)
  34.         {
  35.             UpdateUI?.Invoke(null, updateUIModel);
  36.         }
  37.     }
  38. }
复制代码
客户端执行代码:

点击触发事件:定义如下:
  1. #region << 版 本 注 释 >>
  2. /*----------------------------------------------------------------
  3. * 创建者:码农阿亮
  4. * 创建时间:2023/8/4 08:07:17
  5. * 版本:V1.0.0
  6. * 描述:
  7. *
  8. * ----------------------------------------------------------------
  9. * 修改人:
  10. * 时间:
  11. * 修改说明:
  12. *
  13. * 版本:V1.0.1
  14. *----------------------------------------------------------------*/
  15. #endregion << 版 本 注 释 >>
  16. using CrawlerComm.Handler;
  17. using CrawlerModel.Meitu;
  18. using CrawlerService.Meitu;
  19. using System;
  20. using System.Collections.Generic;
  21. using System.ComponentModel;
  22. using System.Data;
  23. using System.Drawing;
  24. using System.IO;
  25. using System.Linq;
  26. using System.Net;
  27. using System.Text;
  28. using System.Threading.Tasks;
  29. using System.Windows.Forms;
  30. namespace CrawlerData
  31. {
  32.     public partial class FrmMain : Form
  33.     {
  34.         public FrmMain()
  35.         {
  36.             InitializeComponent();
  37.             //订阅委托
  38.             UpdateFrmHandler.UpdateUI += UpdateUIFuc;
  39.         }
  40.         /// <summary>
  41.         /// 更新界面委托方法
  42.         /// </summary>
  43.         /// <param name="sender"></param>
  44.         /// <param name="updateUIModel"></param>
  45.         private void UpdateUIFuc(object sender, UpdateUIModel updateUIModel )
  46.         {
  47.             try
  48.             {
  49.                 //改变界面UI中的值
  50.                 this.Invoke((Action)delegate
  51.                 {
  52.                     UpdateUIBiz(updateUIModel);
  53.                 });
  54.             }
  55.             catch (Exception ex)
  56.             {
  57.               
  58.             }
  59.         }
  60.         /// <summary>
  61.         /// 更新UI界面业务
  62.         /// </summary>
  63.         /// <param name="updateUIModel"></param>
  64.         private void UpdateUIBiz(UpdateUIModel updateUIModel)
  65.         {
  66.             try
  67.             {
  68.                 //分类
  69.                 tbCategory.Text = updateUIModel.Category;
  70.                 //排名
  71.                 tbNo.Text = updateUIModel.beauty.No;
  72.                 //姓名
  73.                 tbName.Text = updateUIModel.beauty.Name;
  74.                 //人气值
  75.                 tbPopularity.Text = updateUIModel.beauty.Popularity;
  76.                 //图片地址
  77.                 tbUrl.Text = updateUIModel.beauty.ImageUrl;
  78.                 //图片
  79.                 WebClient client = new WebClient();
  80.                 string imageUrl = updateUIModel.beauty.ImageUrl;// 要显示的网络图片的URL
  81.                 byte[] imageBytes = client.DownloadData(imageUrl);
  82.                 Image img = Image.FromStream(new MemoryStream(imageBytes));
  83.                 picBox.Image = img;
  84.                 //爬取数量
  85.                 lbNumber.Text = updateUIModel.DownloadNumber.ToString();
  86.                
  87.             }
  88.             catch (Exception ex)
  89.             {
  90.             }
  91.         }
  92.         /// <summary>
  93.         /// 开始执行按钮点击事件
  94.         /// </summary>
  95.         /// <param name="sender"></param>
  96.         /// <param name="e"></param>
  97.         private  void btStart_Click(object sender, EventArgs e)
  98.         {
  99.             StartCrawler();
  100.         }
  101.         /// <summary>
  102.         /// 开始爬取
  103.         /// </summary>
  104.         public async void StartCrawler()
  105.         {
  106.             try
  107.             {
  108.                 MeituParseHtmService meituParseHtml = new MeituParseHtmService();
  109.                 await meituParseHtml.StartAsync();
  110.             }
  111.             catch (Exception ex )
  112.             {
  113.             }
  114.         
  115.         }
  116.     }
  117. }
复制代码
三、爬取验证:

启动客户端:

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

爬取的Json数据结果:


下载的图片资源:

分目录层级存放:

源码链接地址:

Gitee完整实例地址:

https://gitee.com/mingliang_it/CrawlerDataClient
建群声明:本着技术在于分享,方便大家交流学习的初心,特此建立【编程内功修炼交流群】,热烈欢迎各位爱交流学习的程序员进群,也希望进群的大佬能不吝分享自己遇到的技术问题和学习心得


来源:https://www.cnblogs.com/wml-it/archive/2023/08/14/17628041.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x

举报 回复 使用道具