首页 > 其他分享 >.net core 实现简单爬虫—抓取博文列表

.net core 实现简单爬虫—抓取博文列表

时间:2023-06-15 13:35:40浏览次数:36  
标签:core post class 博文 爬虫 HttpCode item net div


概述


HttpCode.Core 源自于HttpCode,不同的是 HttpCode.Core是基于.net standard 2.0实现的,移除了HttpCode与windows相耦合的api,且修改了异步实现,其余特性完全与HttpCode相同

详细



一、介绍一个Http请求框架HttpCode.Core

HttpCode.Core 源自于HttpCode(传送门),不同的是 HttpCode.Core是基于.net standard 2.0实现的,移除了HttpCode与windows相耦合的api,且修改了异步实现,其余特性完全与HttpCode相同,大家 如果在使用中有什么问题可以查看在线文档(传送门

HttpCode.Core完全开源,已传到github,地址:https://github.com/stulzq/HttpCode.Core

为了方便大家使用,也传到了nuget,地址:https://www.nuget.org/packages/HttpCode.Core/,在nuget中搜索 HttpCode.Core 或执行命令 Install-Package HttpCode.Core

具体的使用方法大家可以查阅在线文档,或者查看github。

简单、易用、高效 一个有态度的开源.Net Http请求框架!

二、分析抓取地址

首先使用谷歌浏览器的开发者工具,抓取博客首页获取博文列表的地址:


.net core 实现简单爬虫—抓取博文列表_爬虫

从中我们可以分析出:


Post

3.请求数据



{
    "CategoryType":"SiteHome",
    "ParentCategoryId":0,
    "CategoryId":808,
    "PageIndex":3,
    "TotalPostCount":4000,
    "ItemListActionName":"PostList"
}




PageIndex

我们先使用HttpCode.Core来试一试获取数据:



int pageIndex = 1;//页数
HttpHelpers httpHelpers=new HttpHelpers();
HttpItems items=new HttpItems();
items.Url = "https://www.cn.com/mvc/AggSite/PostList.aspx";//请求地址
items.Method = "Post";//请求方式 post
items.Postdata = "{\"CategoryType\":\"SiteHome\"," +
                    "\"ParentCategoryId\":0," +
                    "\"CategoryId\":808," +
                    "\"PageIndex\":"+ pageIndex + "," +
                    "\"TotalPostCount\":4000," +
                    "\"ItemListActionName\":\"PostList\"}";//请求数据
HttpResults hr = httpHelpers.GetHtml(items);
Console.WriteLine(hr.Html);
Console.ReadKey();



运行截图:


.net core 实现简单爬虫—抓取博文列表_爬虫_02

可以看到我们已经成功获取了数据,证明我们的分析是正确的。

三、解析返回的数据

HtmlAgilityPack

关于这个组件的使用,博客已经有不少介绍此组件的文档,大家可以搜索查看,使用此组件需具备xpath相关知识,我就不在此详细叙述了。

HtmlAgilityPack

  打开程序包控制台

Install-Package HtmlAgilityPack -Version 1.5.2-beta6

2. 解析返回的数据

贴一下返回的部分数据:

<div class="post_item">
<div class="digg">
    <div class="diggit" οnclick="DiggPost('yaoxiaowen',7470460,318439,1)"> 
    <span class="diggnum" id="digg_count_7470460">4</span>
    </div>
    <div class="clear"></div>
    <div id="digg_tip_7470460" class="digg_tip"></div>
</div>      
<div class="post_item_body">
    <h3><a class="titlelnk" href="http://www.cn.com/yaoxiaowen/p/7470460.html" target="_blank">关于跨平台的一些认识</a></h3>                   
    <p class="post_item_summary">
<a href="http://www.cn.com/yaoxiaowen/" target="_blank"><img width="48" height="48" class="pfs" src="//pic.cnblogs.com/face/918357/20161122225949.png" alt=""/></a>    前段时间看了 周志明的那本 《深入理解java虚拟机》。对于 平台无关性 问题,有了一些新的认识。所以特写一篇博客来进行总结。 这是我的第一篇不针对具体技术,而只针对计算机系统和原理的博客文章,而这种话题,总是比较宽泛,而我本人的水平有限,所以我也只能泛泛的写写,思考的不对的地方,还望读者不吝批评。 ...
    </p>              
    <div class="post_item_foot">                    
    <a href="http://www.cn.com/yaoxiaowen/" class="lightblue">eleven_yw</a> 
    发布于 2017-09-03 22:12 
    <span class="article_comment"><a href="http://www.cn.com/yaoxiaowen/p/7470460.html#commentform" title="2017-09-04 15:23" class="gray">
        评论(2)</a></span><span class="article_view"><a href="http://www.cn.com/yaoxiaowen/p/7470460.html" class="gray">阅读(210)</a></span></div>
</div>
<div class="clear"></div>
</div>
<div class="post_item">
<div class="digg">
    <div class="diggit" οnclick="DiggPost('loseheart',7471197,375716,1)"> 
    <span class="diggnum" id="digg_count_7471197">0</span>
    </div>
    <div class="clear"></div>
    <div id="digg_tip_7471197" class="digg_tip"></div>
</div>      
<div class="post_item_body">
    <h3><a class="titlelnk" href="http://www.cn.com/loseheart/p/7471197.html" target="_blank">2017年9月3日  实现网站的权限管理</a></h3>                   
    <p class="post_item_summary">
<a href="http://www.cn.com/loseheart/" target="_blank"><img width="48" height="48" class="pfs" src="//pic.cn.com/face/1224591/20170823222646.png" alt=""/></a>    现在各个企业管理网站对登录的账号都要进行权限管理,并且相当重要,每个账号登录进去所能看到的东西大不相同,下面是实现该功能的一个的一种方法。 需求: 权限:权限是使用者操作系统中功能模块的能力,如“角色管理”模块、“资费管 理”模块和“账单管理”模块等。通过指定权限,可将使用者的操作限定在指定的 范围 ...
    </p>              
    <div class="post_item_foot">                    
    <a href="http://www.cn.com/loseheart/" class="lightblue">Loseheart</a> 
    发布于 2017-09-03 21:34 
    <span class="article_comment"><a href="http://www.cn.com/loseheart/p/7471197.html#commentform" title="" class="gray">
        评论(0)</a></span><span class="article_view"><a href="http://www.cn.com/loseheart/p/7471197.html" class="gray">阅读(354)</a></span></div>
</div>
<div class="clear"></div>
</div>

从中我们不难看出每一个数据是以class=post_item的div来进行区分的,我们想要的博文地址、标题等是在这个div里面的class=post_item_body的div里面,以此类推我们可以分析出:

  • 博文标题 <div class="post_item"> | <div class="post_item_body"> | h3 | a | Text
  • 博文地址 <div class="post_item"> | <div class="post_item_body"> | h3 | a | href
  • ..以此类推

因为HtmlAgilityPack是通过xpath来解析网页的,所以现在我们要根据我们上面分析出的路径来写xpath,这里不明白xpath的可以去w3cschool学习一下,非常简单。

下面是我写好的解析博文标题、地址和作者的代码,抓取其他信息可以自己参考试一试:



//解析数据
HtmlDocument doc=new HtmlDocument();
//加载html
doc.LoadHtml(hr.Html);

//获取 class=post_item_body 的div列表
HtmlNodeCollection itemNodes = doc.DocumentNode.SelectNodes("div[@class='post_item']/div[@class='post_item_body']");

//循环根据每个div解析我们想要的数据

foreach (var item in itemNodes)
{
    //获取包含博文标题和地址的 a 标签
    var nodeA = item.SelectSingleNode("h3/a");
    //获取博文标题
    string title = nodeA.InnerText;
    //获取博文地址 a标签的 href 属性
    string url = nodeA.GetAttributeValue("href", "");

    //获取包含作者名字的 a 标签
    var nodeAuthor = item.SelectSingleNode("div[@class='post_item_foot']/a[@class='lightblue']");
    string author = nodeAuthor.InnerText;

    Console.WriteLine($"标题:{title} | 作者:{author} | 地址:{url}");
}




运行截图:


.net core 实现简单爬虫—抓取博文列表_爬虫_03

四、循环抓取多个分页

PageIndex 是页数,分析单个页面的代码我们也写出来来,那么我们可以通过循环递增页数,来达到抓取不同分页数据的要求。

贴一下完整的代码



int pageIndex = 1;//页数
int maxPageIndex = 10;//最大页数
HttpHelpers httpHelpers=new HttpHelpers();

for (int i = 0; i < maxPageIndex; i++)
{
    HttpItems items = new HttpItems();
    items.Url = "https://www.cn.com/mvc/AggSite/PostList.aspx";//请求地址
    items.Method = "Post";//请求方式 post
    items.Postdata = "{\"CategoryType\":\"SiteHome\"," +
                        "\"ParentCategoryId\":0," +
                        "\"CategoryId\":808," +
                        "\"PageIndex\":" + (i+1) + "," + //因为i从0开始 所以此处我们要加1
                        "\"TotalPostCount\":4000," +
                        "\"ItemListActionName\":\"PostList\"}";//请求数据
    HttpResults hr = httpHelpers.GetHtml(items);

    //解析数据
    HtmlDocument doc = new HtmlDocument();
    //加载html
    doc.LoadHtml(hr.Html);

    //获取 class=post_item_body 的div列表
    HtmlNodeCollection itemNodes = doc.DocumentNode.SelectNodes("div[@class='post_item']/div[@class='post_item_body']");

    Console.WriteLine($"第{i+1}页数据:");

    //循环根据每个div解析我们想要的数据
    foreach (var item in itemNodes)
    {
        //获取包含博文标题和地址的 a 标签
        var nodeA = item.SelectSingleNode("h3/a");
        //获取博文标题
        string title = nodeA.InnerText;
        //获取博文地址 a标签的 href 属性
        string url = nodeA.GetAttributeValue("href", "");

        //获取包含作者名字的 a 标签
        var nodeAuthor = item.SelectSingleNode("div[@class='post_item_foot']/a[@class='lightblue']");
        string author = nodeAuthor.InnerText;
        //输出数据
        Console.WriteLine($"标题:{title} | 作者:{author} | 地址:{url}");
    }

    //每抓取一页数据 暂停三秒
    Thread.Sleep(3000);
}
            
Console.ReadKey();



五、运行截图


六、项目文件截图


.net core 实现简单爬虫—抓取博文列表_数据_04

一个简单的.net core实现的简单爬虫就此完成!



标签:core,post,class,博文,爬虫,HttpCode,item,net,div
From: https://blog.51cto.com/u_7583030/6486255

相关文章

  • .NET中SQL数据库的GraphQL API
    您可能已经阅读了大量关于GraphQL的文章,并且已经了解了这种API技术的所有优缺点,作为RESTAPI的替代方案。但是,让我们不久回顾一下GraphQL是什么,它的主要目的,以及我们如何在现实生活中使用它。关于GraphQL的简短信息GraphQL于2015年由Facebook发布,定位为着名的RESTful架构风格的替代......
  • 【C#/.NET】xUnit和Moq实现TDD
    ​ 目录 前置条件MoqxUnitTDD实践创建项目红灯绿灯重构单元测试一些最佳实践总结 前置条件Moq安装Moq包Install-PackageMoq         Moq是一个Mocking库,通过它可以轻易地模拟对象来进行测试。在我们的例子中,我们将使用Moq来模拟一个数据库......
  • container scale up/ down 原理 in kubernetes
    https://imroc.cc/kubernetes/best-practices/autoscaling/hpa-velocity.html 原理与误区HPA在进行扩缩容时,先是由固定的算法计算出期望副本数: 期望副本数=ceil[当前副本数*(当前指标/期望指标)]其中 当前指标/期望指标 的比例如果接近1(在容忍度范围内,默......
  • Kubernetes 中的 Pod 内存请求(request)和限制(limit)设置多大合适
    Kubernetes中的Pod内存请求(request)和限制(limit)是为容器编排和资源管理提供支持的重要概念。一般来说,合适的内存request和limit需要基于应用程序的内存需求大小、应用程序的容器镜像大小以及在Kubernetes集群中Pod的数量等因素进行考虑。以下是一些关于如何设置Pod的......
  • .NET7 中Autofac依赖注入整合多层,项目中可直接用
    目录一、配置Autofac替换内置DI二、构造函数注入三、属性注入四、批量注入五、手动获取实例六、其它用法1.不用接口,直接注入实例 2.一接口多实现 回到顶部一、配置Autofac替换内置DI1.安装Nuget包:Autofac.Extensions.DependencyInjection 2.Program.cs......
  • gRPC入门与实操(.NET篇)
    为什么选择gRPC#历史#长久以来,我们在前后端交互时使用WebApi+JSON方式,后端服务之间调用同样如此(或者更久远之前的WCF+XML方式)。WebApi+JSON是优选的,很重要的一点是它们两者都是平台无关的三方标准,且足够语义化,便于程序员使用,在异构(前后端、多语言后端)交互场景下是不二......
  • java服务器更换jdk版本后报错:javax.net.ssl.SSLHandshakeException: No appropriate p
    java,服务器更换jdk版本后报错:Causedby:javax.net.ssl.SSLHandshakeException:Noappropriateprotocol(protocolisdisabledorciphersuitesareinappropriate)然后数据库出现:###Errorqueryingdatabase.Cause:java.lang.reflect.UndeclaredThrowableExc......
  • 全面的ASP.NET Core Blazor简介和快速入门
    思维导航前言Blazor是什么?Blazor的优势和特点Blazor的劣势Blazor支持的平台Blazor三种托管模型及其各自特点如何选择要使用的托管模型?Razor语法简述新建ZeroBlazor空白解决方案使用VS2022快速创建BlazorServer应用使用VS2022快速创建BlazorWebAssembly应用课外......
  • 海康SDK注册报错 Structure.getFieldOrder() on class com.xxx.sdk.HCNetSDK$NET_DVR_
    Structure.getFieldOrder()onclasscom.xxx.sdk.HCNetSDK$NET_DVR_DEVICEINFO_V30doesnotprovideenoughnames[0]海康依赖的版本较低,项目引用的较高,导致海康注册报错,所以降低jna版本 <dependency><groupId>net.java.dev.jna</groupId><artifactId>jna<......
  • 浅谈 .NET 中的对象引用、非托管指针和托管指针
    目录前言一、对象引用二、值传递和引用传递三、初识托管指针和非托管指针四、非托管指针1、非托管指针不能指向对象引用2、类成员指针五、托管指针 前言#本文主要是以C#为例介绍.NET中的三种指针类型(本文不包含对于函数指针的介绍):对象引用、非托管指针、......