HtmlAgilityPack组件
HtmlAgilityPack组件用于解析Html字符串,一个典型的应用场景是用于网页爬虫。
示例程序
using Common.Tools;
using Datebase.Entity;
using HtmlAgilityPack;
using Http.Extension;
using ServiceStack.Orm.Extension.Imples;
using ServiceStack.Orm.Extension.Interface;
using ServiceStack.OrmLite;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks; namespace WebSpider
{
class Program
{
public static IOrmClient dbClient = new OrmClient(ConfigurationManager.ConnectionStrings["mssql"].ConnectionString, SqlServerDialect.Provider);
static void Main(string[] args)
{
List<Task> tasks = FetchSinger();
Task.WaitAll(tasks.ToArray());
Console.WriteLine("歌手信息抓取完毕!");
Console.ReadLine();
} /// <summary>
/// 网页爬虫程序,从音乐网站获取最热的前100位歌手的信息
/// </summary>
private static List<Task> FetchSinger()
{
List<Task> tasks = new List<Task>();
HttpResult result = HttpCore.Send(new HttpItem()
{
URL = "http://mp3.sogou.com/static_new/topsinger_remen.html",
Method = MethodType.GET
});
HtmlDocument document = new HtmlDocument();
document.LoadHtml(result.Html);
var rootNode = document.DocumentNode;
//获取第1到第10位歌手
var top10Nodes = rootNode.SelectNodes("//div[@id='right2']/ul[@class='singerlist2']/li/a");
if (top10Nodes != null)
{
Task t = new Task(nodes =>
{
var singerNodes = nodes as HtmlNodeCollection;
if (singerNodes != null)
{
foreach (var hrefNode in singerNodes)
{
//歌手链接
var link = hrefNode.GetAttributeValue("href", "");
//歌手的序列号码
var noNode = hrefNode.SelectSingleNode("./strong[@class='singertop10']");
if (noNode != null)
{
int sNo = -;
int.TryParse(noNode.InnerText.Replace("Top", "").Trim(), out sNo);
SingerDetail(sNo, link);
}
}
}
}, top10Nodes);
t.Start();
tasks.Add(t);
}
//获取第11到第100位歌手
var tbNodes = rootNode.SelectNodes("//table[@class='indextable']");
//遍历捕获的所有的table对象
foreach (var e in tbNodes)
{
Task t = new Task(p =>
{
var tbNode = p as HtmlNode;
if (tbNode != null)
{
var hrefNodes = tbNode.SelectNodes("./tbody/tr/td/a");
if (hrefNodes != null)
{
foreach (var href in hrefNodes)
{
//序号
var sNo = -;
var trNode = href.ParentNode.PreviousSibling.PreviousSibling;
if (trNode != null)
{
int.TryParse(trNode.InnerText.Trim().TrimEnd('.'), out sNo);
}
var link = href.GetAttributeValue("href", "");
if (!string.IsNullOrEmpty(link))
{
SingerDetail(sNo, link);
}
}
}
}
}, e);
t.Start();
tasks.Add(t);
}
return tasks;
} /// <summary>
/// 通过歌手链接访问歌手详细信息
/// </summary>
/// <param name="sNo">序列号</param>
/// <param name="link">歌手的链接地址</param>
private static void SingerDetail(int sNo, string link)
{
var linkResult = HttpCore.Send(new HttpItem()
{
URL = link,
Method = MethodType.GET
});
if (!string.IsNullOrEmpty(linkResult.Html))
{
T_Singer user = new T_Singer();
user.ID = Utility.GenerateId();
user.SerialNumber = sNo;
user.IsApprove = true;
user.CreateBy = "admin";
user.CreateDate = DateTime.Now;
user.ModifyBy = "admin";
user.ModifyDate = DateTime.Now;
HtmlDocument linkDoc = new HtmlDocument();
linkDoc.LoadHtml(linkResult.Html);
//姓名/昵称
var name = linkDoc.DocumentNode.SelectSingleNode("//div[@class='song_tit']");
if (name != null)
{
user.RealName = user.NickName = name.InnerText.Trim().Replace("<br>", System.Environment.NewLine);
}
//包含个人信息的所有的li元素
var lis = linkDoc.DocumentNode.SelectNodes("//ul[@class='song_detail']/li");
//国籍
var Nationality = linkDoc.DocumentNode.SelectSingleNode("//ul[@class='song_detail']/li[1]/span");
user.Nationality = Search(lis, "国籍");
//出生地
user.Birthplace = Search(lis, "出生地");
//出生日期
//出生日期
var temp = Search(lis, "出生日期");
var match = Regex.Match(temp, @"\d{0,4}年\d{1,2}月\d{1,2}日");
var bir = string.Empty;
if (match != null)
{
var birArr = match.Value.Split(new string[] { "年", "月", "日" }, StringSplitOptions.RemoveEmptyEntries);
if (birArr.Length > )
bir += birArr[];
if (birArr.Length > )
bir += "-" + birArr[];
if (birArr.Length > )
bir += "-" + birArr[];
}
DateTime bDay = new DateTime(, , );
if (DateTime.TryParse(bir, out bDay))
user.Birthday = bDay;
//星座
user.Constellation = Search(lis, "星座");
//简介
var selfDescNode = linkDoc.GetElementbyId("desc_long");
selfDescNode = selfDescNode ?? linkDoc.GetElementbyId("desc_short");
if (selfDescNode != null)
user.BriefIntroduction = selfDescNode.InnerText.Replace("<br>", "").Trim();
dbClient.Insert(user);
}
} /// <summary>
/// 从节点中查找指定数据方法
/// </summary>
private static string Search(HtmlNodeCollection nodes, string key)
{
if (nodes != null)
{
foreach (var node in nodes)
{
if (node.FirstChild.InnerText.Trim().StartsWith(key))
{
var spanNode = node.SelectSingleNode("./span");
if (spanNode != null)
{
return spanNode.InnerText.Trim().Replace("<br>", System.Environment.NewLine);
}
}
}
}
return string.Empty;
}
}
}
HtmlAgilityPack组件的更多相关文章
- 【原创】C#玩高频数字彩快3的一点体会
购彩风险非常高,本人纯属很久以前对数字高频彩的一点研究.目前已经远离数字彩,重点研究足球篮球比赛资料库和赛果预测. 这是一篇在草稿箱保存了1年多的文章,一直没发现,顺便修改修改分享给大家.以后会有更多 ...
- C#搭建足球赛事资料库与预测平台(1) 基本介绍
本博客所有文章分类的总目录:[总目录]本博客博文总目录-实时更新 开源C#彩票数据资料库系列文章总目录:[目录]C#搭建足球赛事资料库与预测平台与彩票数据分析目录 去年4月到现在,一年 ...
- EWS Managed API 2.0 设置获取邮件自动回复功能
摘要 最近要在邮件提醒功能中添加,自动回复的功能.在移动端获取用户在outlook上是否开启了自动回复功能,如果用户在outlook上开启了自动回复功能, 获取用户自动回复的内容,如果没有开启,用户可 ...
- 使用.Net Core做个爬虫
最近接手一个新项目,爬亚马逊分类.商品数据.记得大学的时候,自己瞎玩,写过一个爬有缘网数据的程序,那个时候没有考虑那么多,写的还是单线程,因为网站没有反爬,就不停的一直请求,记得放到实验室电脑上一天, ...
- NET 5 爬虫框架/抓取数据
爬虫大家或多或少的都应该接触过的,爬虫有风险,抓数需谨慎. 爬虫有的是抓请求,有的是抓网页再解析 本着研究学习的目的,记录一下在 .NET Core 下抓取数据的实际案例.爬虫代码一般具有时效性,当 ...
- c#中的解析HTML组件 -- (HtmlAgilityPack,Jumony,ScrapySharp,NSoup,Fizzler)
做数据抓取,网络爬虫方面的开发,自然少不了解析HTML源码的操作.那么问题来了,到底.NET如何来解析HTML,有哪些解析HTML源码的好用的,有效的组件呢? 作者在开始做这方面开发的时候就被这些 ...
- c# 爬虫和组件HtmlAgilityPack处理html
测试当前爬虫的User-Agent:http://www.whatismyuseragent.net/ 大佬的博客地址:https://www.cnblogs.com/jjg0519/p/670274 ...
- HTML解析组件HtmlAgilityPack使用
HtmlAgilityPack是一个开源的解析HTML元素的类库,最大的特点是可以通过XPath来解析HMTL,如果您以前用C#操作过XML,那么使用起HtmlAgilityPack也会得心应手.目前 ...
- C#+HtmlAgilityPack+XPath带你采集数据(以采集天气数据为例子)
第一次接触HtmlAgilityPack是在5年前,一些意外,让我从技术部门临时调到销售部门,负责建立一些流程和寻找潜在客户,最后在阿里巴巴找到了很多客户信息,非常全面,刚开始是手动复制到Excel, ...
随机推荐
- 用Docker Compose启动Nginx和Web等多个镜像
安装docker-compose 运行命令 curl -L "https://github.com/docker/compose/releases/download/1.9.0/docker ...
- SOA架构介绍和理解
SOA架构介绍和理解 SOA的正确方法论及目标模型,其实SOA在实现架构落地上,需要考虑到对服务的组合,不断的重用现有的服务,让企业应用可以逐步集成,快速实现业务的迭代. 通过SOA架构分层将服务按照 ...
- mac下webpagetest搭建
我的server和agent都是在mac上搭建的,所以会和linux下有些不同 一.安装配置Apache和PHP webpagetest需要使用PHP和Apache启动服务.mac默认安装了Apa ...
- Android中的事件传递机制
Android源码版本:API Level 19(Android 4.4) Android事件构成 在Android中,事件主要包括点按.长按.拖拽.滑动等,点按又包括单击和双击,另外还包括单指操作和 ...
- ANDROID开发之问题积累及解决方案(一)
一.activity跳转及传值 当进行activity之间的跳转时我们会遇到这样的问题.首先熟悉下activity之间跳转.Activity跳转与传值,主要是通过Intent类来连接多个Activit ...
- linux下驱动webcam
linux自带驱动只支持一些型号的camera,具体型号见http://www.ideasonboard.org/uvc/ 所以有些购买的webcam不能够在linux中被点亮,而且有些厂家只为了在W ...
- oracle分页查询sql
select * from( select shopid,rownum rn from p_shopinfo where is_hot=1 and rownum <=6 order by sho ...
- 脚本录制(JMeter)
使用JMeter录制脚本: 1.打开JMeter工具,创建一个线程组,接着创建一个http代理服务器,代理服务器设置如下:
- 记一次TFS 的 垃圾提示(无法下载 未获取项目 的 代码)
提示 “ 所有文件都是最新的 ”,但是在 源码管理 里面 确是 “未下载” 我艹,第一次遇到.如图.~~ 最后发现是 TFS 的项目权限设置问题. 你妈个马批的,啥子鸡巴破B提示,太阳你妈B 的 .要 ...
- 使用AS编译jni文件无法编译出arm64-v8a,x86_64和mips64平台的.so文件的解决方法
我用的插件版本是:classpath 'com.android.tools.build:gradle-experimental:0.4.0',AS集成和使用ndk编译项目参考官方demo:https: ...