.NET爬取美图官网首页数据实战
前言:
在当今信息化社会,网络数据分析越来越受到重视。而作为开发人员,掌握一门能够抓取网页内容的语言显得尤为重要。在此篇文章中,将分享如何使用 .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安装引用:
dotnet add package HtmlAgilityPack --version 1.11.51
二、实现核心代码:
设计定义实体:
网站爬取信息:
爬取信息实体定义:根据美图的首页展示的信息分析,进行定义爬取字段的信息,定义如下:
#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:
爬取的Json数据结果:
下载的图片资源:
分目录层级存放:
源码链接地址:
Gitee完整实例地址:
建群声明:本着技术在于分享,方便大家交流学习的初心,特此建立【编程内功修炼交流群】,热烈欢迎各位爱交流学习的程序员进群,也希望进群的大佬能不吝分享自己遇到的技术问题和学习心得
.NET爬取美图官网首页数据实战的更多相关文章
- 手把手教大家如何用scrapy爬虫框架爬取王者荣耀官网英雄资料
之前被两个关系很好的朋友拉入了王者荣耀的大坑,奈何技术太差,就想着做一个英雄的随查手册,这样就可以边打边查了.菜归菜,至少得说明咱打王者的态度是没得说的,对吧?大神不喜勿喷!!!感谢!!废话不多说,开 ...
- python多线程爬取斗图啦数据
python多线程爬取斗图啦网的表情数据 使用到的技术点 requests请求库 re 正则表达式 pyquery解析库,python实现的jquery threading 线程 queue 队列 ' ...
- 一款仿PBA官网首页jQuery焦点图的切换特效
一款仿PBA官网首页jQuery焦点图的切换特效,非常的简单大方, 在对浏览器兼容性的方面做了不少的功夫.IE6也勉强能过去. 还是一款全屏的焦点图切换特效.大气而清新.很适合简介大方的网站. 下图还 ...
- 爬取斗图网图片,使用xpath格式来匹配内容,对请求伪装成浏览器, Referer 防跨域请求
6.21自我总结 一.爬取斗图网 1.摘要 使用xpath匹配规则查找对应信息文件 将请求伪装成浏览器 Referer 防跨域请求 2.爬取代码 #导入模块 import requests #爬取网址 ...
- Axure实现vcg官网首页原型图
W240第二天第三天 Axure的简单使用: 作业实现:vcg官网首页原型图 帮助文档基础篇:原型图基础之axure线框图设计 导航栏设计: 添加通用母版header 导航栏设计注意: 鼠标移动到下面 ...
- Python3爬取人人网(校内网)个人照片及朋友照片,并一键下载到本地~~~附源代码
题记: 11月14日早晨8点,人人网发布公告,宣布人人公司将人人网社交平台业务相关资产以2000万美元的现金加4000万美元的股票对价出售予北京多牛传媒,自此,人人公司将专注于境内的二手车业务和在美国 ...
- Java爬虫系列之实战:爬取酷狗音乐网 TOP500 的歌曲(附源码)
在前面分享的两篇随笔中分别介绍了HttpClient和Jsoup以及简单的代码案例: Java爬虫系列二:使用HttpClient抓取页面HTML Java爬虫系列三:使用Jsoup解析HTML 今天 ...
- Python协程爬取妹子图(内有福利,你懂得~)
项目说明: 1.项目介绍 本项目使用Python提供的协程+scrapy中的选择器的使用(相当好用)实现爬取妹子图的(福利图)图片,这个学会了,某榴什么的.pow(2, 10)是吧! 2.用到的知 ...
- Python3爬虫系列:理论+实验+爬取妹子图实战
Github: https://github.com/wangy8961/python3-concurrency-pics-02 ,欢迎star 爬虫系列: (1) 理论 Python3爬虫系列01 ...
- 针对石家庄铁道大学官网首页的UI分析
身为一名光荣的铁大铮铮学子,我对铁大的网站首页非常的情有独钟,下面我就石家庄铁道大学的官网首页进行UI分析: 1.在首页最醒目的地方赫然写着石家庄铁道大学七个大字,让人一眼就豁然开朗. 2.网站有EN ...
随机推荐
- 2023-03-18:给定一个长度n的数组,每次可以选择一个数x, 让这个数组中所有的x都变成x+1,问你最少的操作次数, 使得这个数组变成一个非降数组。 n <= 3 * 10^5, 0 <= 数值
2023-03-18:给定一个长度n的数组,每次可以选择一个数x, 让这个数组中所有的x都变成x+1,问你最少的操作次数, 使得这个数组变成一个非降数组. n <= 3 * 10^5, 0 &l ...
- 2022-08-19:以下go语言代码输出什么?A:equal;B:not equal;C:不确定。 package main import ( “fmt“ “reflect“ )
2022-08-19:以下go语言代码输出什么?A:equal:B:not equal:C:不确定. package main import ( "fmt" "refle ...
- 2020-10-28:go中,好几个go程,其中一个go程panic,会产生什么问题?
福哥答案2020-10-28: 1.运行时恐慌,当panic被抛出异常后,如果我们没有在程序中添加任何保护措施的话,程序就会打印出panic的详细情况之后,终止运行.2.有panic的子协程里的def ...
- 2022-07-26:以下go语言代码输出什么?A:5;B:hello;C:编译错误;D:运行错误。 package main import ( “fmt“ ) type integer in
2022-07-26:以下go语言代码输出什么?A:5:B:hello:C:编译错误:D:运行错误. package main import ( "fmt" ) type inte ...
- 2021-08-26:长度为N的数组arr,一定可以组成N^2个数字对。例如arr = [3,1,2],数字对有(3,3) (3,1) (3,2) (1,3) (1,1) (1,2) (2,3) (2
2021-08-26:长度为N的数组arr,一定可以组成N^2个数字对.例如arr = [3,1,2],数字对有(3,3) (3,1) (3,2) (1,3) (1,1) (1,2) (2,3) (2 ...
- Github疯传!200本计算机经典书籍!
好书在精不在多,每一本经典书籍都值得反复翻阅,温故而知新! 下面分享几本计算机经典书籍,都是我自己看过的. 重构 改善既有代码的设计 就像豆瓣评论所说的,看后有种醍醐灌顶.欲罢不能的感觉.无论你是初学 ...
- cv学习总结(11.14-11.20)
本周主要完成了assignment2中的connected_layer部分的代码,跟assignment1中的two_layer_net相比,虽然整体思路都是实现全连接的网络,但是connect_la ...
- LeetCode 周赛 347(2023/05/28)二维空间上的 LIS 最长递增子序列问题
本文已收录到 AndroidFamily,技术和职场问题,请关注公众号 [彭旭锐] 提问. 往期回顾:LeetCode 单周赛第 346 场 · 仅 68 人 AK 的最短路问题 周赛 347 概览 ...
- 系统MySQL服务无法启动报错1067的四种解决方法win7系统MySQL服务无法启动报错1067的四种解决方法
有些win7系统用户在登陆mysql或者重装mysql时出现"无法启动MYSQL服务,错误1067",而且重启.修复注册表都没办法解决问题.那么遇到MySQL服务无法启动问 ...
- Jackson前后端开发模式必备json利器
前言 json是我们现代互联网程序最常用的交互格式,是否你在工作中会遇到前端说字段不一致需要改的需求,是否遇到过数据库字段名与javaBean的规范不同,是否遇到过json与javaBean相互转换时 ...