.NET Core 下的爬虫利器

爬虫大家或多或少的都应该接触过的,爬虫有风险,抓数需谨慎。

本着研究学习的目的,记录一下在 .NET Core 下抓取数据的实际案例。爬虫代码一般具有时效性,当我们的目标发生改版升级,规则转换后我们写的爬虫代码就会失效,需要重新应对。抓取数据的主要思路就是去分析目标网站的页面逻辑,利用xpath、正则表达式等知识去解析网页拿到我们想要的数据。

本篇主要简单介绍三个组件的使用,HtmlAgilityPackAngleSharpPuppeteerSharp,前两个可以处理传统的页面,无法抓取单页应用,如果需要抓取单页应用可以使用PuppeteerSharp

关于这三个组件库的实际应用可以参考一下定时任务最佳实战系列文章。

新建一个控制台项目,抓取几个站点的数据来试试,先做准备工作,添加一个IHotNews的接口。

using System.Collections.Generic;
using System.Threading.Tasks;namespace SpiderDemo
{public interface IHotNews{Task<IList<HotNews>> GetHotNewsAsync();}
}

HotNews模型,包含标题和链接

namespace SpiderDemo
{public class HotNews{public string Title { get; set; }public string Url { get; set; }}
}

最终我们通过依赖注入的方式,将抓取到的数据展示到控制台中。

HtmlAgilityPack

  • https://html-agility-pack.net/

  • https://github.com/zzzprojects/html-agility-pack

在项目中安装HtmlAgilityPack组件

Install-Package HtmlAgilityPack

这里以博客园为抓取目标,我们抓取首页的文章标题和链接。

using HtmlAgilityPack;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;namespace SpiderDemo
{public class HotNewsHtmlAgilityPack : IHotNews{public async Task<IList<HotNews>> GetHotNewsAsync(){var list = new List<HotNews>();var web = new HtmlWeb();var htmlDocument = await web.LoadFromWebAsync("https://www.cnblogs.com/");var node = htmlDocument.DocumentNode.SelectNodes("//*[@id='post_list']/article/p/div/a").ToList();foreach (var item in node){list.Add(new HotNews{Title = item.InnerText,Url = item.GetAttributeValue("href", "")});}return list;}}
}

添加HotNewsHtmlAgilityPack.cs实现IHotNews接口,访问博客园网址,拿到HTML数据后,使用xpath语法解析HTML,这里主要是拿到a标签即可。

通过查看网页分析可以得到这个xpath://*[@id='post_list']/article/p/div/a

然后在Program.cs中注入IHotNews,循环遍历看看效果。

using Microsoft.Extensions.DependencyInjection;
using System;
using System.Linq;
using System.Threading.Tasks;namespace SpiderDemo
{class Program{static async Task Main(string[] args){IServiceCollection service = new ServiceCollection();service.AddSingleton<IHotNews, HotNewsHtmlAgilityPack>();var provider = service.BuildServiceProvider().GetRequiredService<IHotNews>();var list = await provider.GetHotNewsAsync();if (list.Any()){Console.WriteLine($"一共{list.Count}条数据");foreach (var item in list){Console.WriteLine($"{item.Title}\t{item.Url}");}}else{Console.WriteLine("无数据");}}}
}

AngleSharp

  • https://anglesharp.github.io/

  • https://github.com/AngleSharp/AngleSharp

在项目中安装AngleSharp组件

Install-Package AngleSharp

同样的,新建一个HotNewsAngleSharp.cs也实现IHotNews接口,这次使用AngleSharp抓取。

using AngleSharp;
using System.Collections.Generic;
using System.Threading.Tasks;namespace SpiderDemo
{public class HotNewsAngleSharp : IHotNews{public async Task<IList<HotNews>> GetHotNewsAsync(){var list = new List<HotNews>();var config = Configuration.Default.WithDefaultLoader();var address = "https://www.cnblogs.com";var context = BrowsingContext.New(config);var document = await context.OpenAsync(address);var cellSelector = "article.post-item";var cells = document.QuerySelectorAll(cellSelector);foreach (var item in cells){var a = item.QuerySelector("p>div>a");list.Add(new HotNews{Title = a.TextContent,Url = a.GetAttribute("href")});}return list;}}
}

AngleSharp解析数据和HtmlAgilityPack的方式有所不同,AngleSharp可以利用css规则去获取数据,用起来也是挺方便的。

Program.cs中注入IHotNews,循环遍历看看效果。

using Microsoft.Extensions.DependencyInjection;
using System;
using System.Linq;
using System.Threading.Tasks;namespace SpiderDemo
{class Program{static async Task Main(string[] args){IServiceCollection service = new ServiceCollection();service.AddSingleton<IHotNews, HotNewsAngleSharp>();var provider = service.BuildServiceProvider().GetRequiredService<IHotNews>();var list = await provider.GetHotNewsAsync();if (list.Any()){Console.WriteLine($"一共{list.Count}条数据");foreach (var item in list){Console.WriteLine($"{item.Title}\t{item.Url}");}}else{Console.WriteLine("无数据");}}}
}

PuppeteerSharp

  • https://www.puppeteersharp.com/

  • https://github.com/hardkoded/puppeteer-sharp

PuppeteerSharp是基于Puppeteer的,Puppeteer 是一个Google 开源的NodeJS 库,它提供了一个高级API 来通过DevTools协议控制Chromium 浏览器。Puppeteer 默认以无头(Headless) 模式运行,但是可以通过修改配置运行“有头”模式。

PuppeteerSharp可以干很多事情,不光可以用来抓取单页应用,还可以用来生成页面PDF或者图片,可以做自动化测试等。

在项目中安装PuppeteerSharp组件

Install-Package PuppeteerSharp

使用PuppeteerSharp第一次会帮我们在项目根目录中下载浏览器执行程序,这个取决于当前网速的快慢,建议手动下载后放在指定位置即可。

using PuppeteerSharp;
using System.Threading.Tasks;namespace SpiderDemo
{class Program{static async Task Main(string[] args){// 下载浏览器执行程序await new BrowserFetcher().DownloadAsync(BrowserFetcher.DefaultRevision);// 创建一个浏览器执行实例using var browser = await Puppeteer.LaunchAsync(new LaunchOptions{Headless = true,Args = new string[] { "--no-sandbox" }});// 打开一个页面using var page = await browser.NewPageAsync();// 设置页面大小await page.SetViewportAsync(new ViewPortOptions{Width = 1920,Height = 1080});}}
}

上面这段代码是初始化PuppeteerSharp必要的代码,可以根据实际开发需要进行修改,下面以"https://juejin.im"为例,演示几个常用操作。

获取单页应用HTML

...
var url = "https://juejin.im";
await page.GoToAsync(url, WaitUntilNavigation.Networkidle0);
var content = await page.GetContentAsync();
Console.WriteLine(content);

可以看到页面上的HTML全部被获取到了,这时候就可以利用规则解析HTML,拿到我们想要的数据了。

保存为图片

...
var url = "https://juejin.im/";
await page.GoToAsync(url, WaitUntilNavigation.Networkidle0);await page.ScreenshotAsync("juejin.png");

保存为PDF

var url = "https://juejin.im/";
await page.GoToAsync(url, WaitUntilNavigation.Networkidle0);await page.PdfAsync("juejin.pdf");

PuppeteerSharp的功能还有很多,比如页面注入HTML、执行JS代码等,使用的时候可以参考官网示例。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/307845.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Redux从入门到进阶,看这一篇就够了!

Redux&#xff0c;带你从入门到进阶&#x1f302;序言☂️一、基础知识1、Redux概念简述2、Redux的工作流程&#x1f383;二、使用Antd实现TodoList页面布局1、在项目中使用Antd2、使用Antd实现TodoList的基本布局3、创建redux中的store&#xff08;1&#xff09;创建store&…

ASP.NET Core 3.x控制IHostedService启动顺序浅探

想写好中间件&#xff0c;这是基础。一、前言今天这个内容&#xff0c;基于于ASP.NET Core 3.x。从3.x开始&#xff0c;ASP.NET Core使用了通用主机模式。它将WebHostBuilder放到了通用的IHost之上&#xff0c;这样可以确保Kestrel可以运行在IHostedService中。我们今天就来研究…

com.mysql.cj.exceptions.InvalidConnectionAttributeException

一:java连接数据库报错 com.mysql.cj.exceptions.InvalidConnectionAttributeException 二:报错原因 MySQL jdbc 6.0 版本以上必须配置“serverTimezone”参数 UTC代表的是全球标准时间 若我们使用的时间是北京时区也就是东八区&#xff0c;领先UTC八个小时。url的时区使用…

Istio Pilot 源码分析(一)

张海东&#xff0c; ‍多点生活&#xff08;成都&#xff09;云原生开发工程师。Istio 作为目前 Servic Mesh 方案中的翘楚&#xff0c;吸引着越来越多的企业及开发者。越来越多的团队想将其应用于微服务的治理&#xff0c;但在实际落地时却因为不了解 Istio 黑盒中的运行机制而…

结营啦!有缘相聚于青训,未来高处见呀~~

&#x1f4f8;叮&#xff01; 记 字节跳动第一届青训营顺利结营啦&#xff01; 从8月份的青训营&#xff0c;到9月份的实训营&#xff0c;搁置了许久的结营心得终于拾起来辽&#xff01; &#x1f3ac;开营进行时 从答疑会开始&#xff0c;负责人仔细的阐述了本次训练营的…

MVC三层架构(详解)

1:初始MVC (1):三层架构 三层架构是指&#xff1a;视图层 View、服务层 Service&#xff0c;与持久层 Dao。它们分别完成不同的功能。 View 层&#xff1a;用于接收用户提交请求的代码在这里编写。 Service 层&#xff1a;系统的业务逻辑主要在这里完成。 Dao 层&#xff1a;…

「offer来了」保姆级巩固你的js知识体系(4.0w字)

「面试专栏」前端面试之JavaScript篇&#x1f9d0;序言&#x1f973;思维导图环节&#x1f60f;一、JS规范1、说几条JavaScript的基本规范。2、对原生JavaScript的了解。3、说下对JS的了解吧。4、JS原生拖拽节点5、谈谈你对ES6的理解6、知道ES6的class嘛&#xff1f;7、说说你对…

写作是人生最大的杠杆

职场&认知洞察 丨 作者 / 易洋 这是findyi公众号的第71篇原创文章不知不觉&#xff0c;公众号写作已经持续了9个月了。去年11月底&#xff0c;心血来潮写了第一篇文章&#xff0c;更多是为了复盘过去的一些工作经历。在前几天&#xff0c;读者数突破了3万&#xff0c;虽然…

拥塞控制(详解)

一&#xff1a;TCP的拥塞控制 1:是什么 (1):是什么(拥塞现象) 网络的 吞吐量 与 通信子网 负荷(即通信子网中正在传输的分组数)有着密切的关系。当 通信子网 负荷比较小时,网络的 吞吐量 (分组数/秒)随网络负荷(每个 节点 中分组的平均数)的增加而线性增加。当网络负荷增加到…

解决 WPF 绑定集合后数据变动界面却不更新的问题(使用 ObservableCollection)

解决 WPF 绑定集合后数据变动界面却不更新的问题独立观察员 2020 年 9 月 9 日在 .NET Core 3.1 的 WPF 程序中打算用 ListBox 绑定显示一个集合&#xff08;满足需求即可&#xff0c;无所谓什么类型的集合&#xff09;&#xff0c;以下是 Xaml 代码&#xff08;瞟一眼就行&…

Kubernetes Liveness and Readiness Probes

在设计关键任务、高可用应用程序时&#xff0c;弹性是要考虑的最重要因素之一。当应用程序可以快速从故障中恢复时&#xff0c;它便具有弹性。云原生应用程序通常设计为使用微服务架构&#xff0c;其中每个组件都位于容器中。为了确保Kubernetes托管的应用程序高可用&#xff0…

「offer来了」2种递进学习思维,24道计网题目,保姆级巩固你的计网知识体系

「面试专栏」前端面试之计算机网络篇⚾序言&#x1f3d0;一、基础知识环节1、专栏学习2、书籍学习⚽二、思维导图环节&#x1f3b3;三、OSI七层模型1、OSI模型是什么&#xff1f;2、OSI七层模型遵循原则&#x1f3cf;四、TCP与UDP1、TCP与UDP的区别2、TCP/UDP的优缺点&#xff…

leetcode236. 二叉树的最近公共祖先

一:题目 二:上码 /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode(int x) : val(x), left(NULL), right(NULL) {}* };*/ class Solution { public:/**思路:1.这里我们需要的是从底向上开…

进击吧! Blazor !第二期 页面制作

Blazor 是一个 Web UI 框架&#xff0c;可通过 WebAssembly 在任意浏览器中运行 .Net 。Blazor 旨在简化快速的单页面 .Net 浏览器应用的构建过程&#xff0c;它虽然使用了诸如 CSS 和 HTML 之类的 Web 技术&#xff0c;但它使用 C&#xff03;语言和 Razor 语法代替 JavaScrip…

「软件项目管理」一文详解软件项目管理概述

一文详解软件项目管理概述&#x1f6b5;前言&#x1f93d;一、项目与软件项目1、项目的定义2、项目的特征3、项目与日常运作举例&#xff08;1&#xff09;判断哪些活动是项目&#xff08;2&#xff09;举例结果&#xff08;3&#xff09;项目与日常运作区别总结4、软件项目的特…

初识ABP vNext(9):ABP模块化开发-文件管理

点击上方蓝字"小黑在哪里"关注我吧创建模块模块开发应用服务运行模块单元测试模块使用前言在之前的章节中介绍过ABP扩展实体&#xff0c;当时在用户表扩展了用户头像字段&#xff0c;用户头像就涉及到文件上传和文件存储。文件上传是很多系统都会涉及到的一个基础功能…

「offer来了」浏览器原理被问懵?5大知识板块巩固你的http知识体系(3.6w字)

「面试专栏」前端面试之浏览器原理篇&#x1f3d4;️序言&#x1f304;一、http和https协议&#xff08;一&#xff09;http和https之间的关系&#x1f9ed;1、http和https是什么&#xff1f;2、http和https的区别&#xff08;二&#xff09;http协议&#x1f9ed;1、http1.0、…

使用Azure DevOps Pipeline实现.Net Core程序的CD

上一次我们讲了使用Azure DevOps Pipeline实现.Net Core程序的CI。这次我们来演示下如何使用Azure DevOps实现.Net Core程序的CD。实现本次目标我们除了Azure DevOps外还需要&#xff1a;一台安装了Docker的主机一个 Docker Hub 账号上一次我们的CI实现了&#xff1a;发布>编…

TCP四次挥手(详解)

一:TCP四次挥手 1:图示 二:TCP四次挥手的过程 所谓的四次挥手即TCP连接的释放(解除)。连接的释放必须是一方主动释放&#xff0c;另一方被动释放。挥手之前主动释放连接的客户端结束ESTABLISHED阶段。随后开始“四次挥手”&#xff1a; a:首先客户端想要释放连接&#xff0c…

「软件项目管理」项目初始——项目确立与生存期模型

「软件项目管理」项目初始阶段——项目确立与生存期模型&#x1f6f0;️序言Preface&#x1f680;一、项目评估1、评估内容2、净利润与投资回报率3、举例阐述&#x1fa90;二、项目立项1、立项流程2、Make or Buy决策3、Make or Buy决策实例&#x1f6f8;三、项目招投标1、项目…