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, ...
随机推荐
- ueditor使用canvas在图片上传前进行压缩
之前就看到H5使用canvas就可以在前端使用JS压缩图片,这次接到任务要把这个功能嵌入到ueditor里面去,以节省流量,减轻服务器压力. H5使用canvas进行压缩的代码有很多,核心原理就是创建 ...
- android ListView子布局中按钮响应点击事件
只需要在子布局的根布局中添加以下属性即可: android:descendantFocusability="blocksDescendants"
- CSS布局中的水平垂直居中
CSS布局中的水平垂直居中 各位好,先说两句题外话.今天是我开通博客园的博客第一天,虽然我申请博客园的账号已经有一年半了,但是由于各种原因迟迟没有开通自己的博客.今天非常有幸开通博客,在此也写一篇关于 ...
- 驱动开发学习笔记. 0.02 基于EASYARM-IMX283 烧写uboot和linux系统
驱动开发读书笔记. 0.02 基于EASYARM-IMX283 怎么烧写自己裁剪的linux内核?(非所有arm9通用) 手上有一块tq2440,但是不知道什么原因,没有办法烧boot进norflas ...
- LDAP与SSH
一般情况下,客户端配置好之后,ssh是可以直接用的,若不能,则需手动配置 1:vim /etc/ssh/sshd_config 把UsePAM改成yes 2:在vim /etc/pam.d/sshd添 ...
- JavaScript Dom基础
一.DOM查找 1.document.getElementById("id") -功能:返回对拥有指定ID的第一个对象的引用 -返回值:DOM对象 -说明:id为DOM元素上id属 ...
- JS中变量名作为if条件的 true/flase
在Javascript中,可以直接将变量名放到if条件中, var a;//甚至不定义 if (a){ //... } 以下情况被认为是flase: 1.''空的字符串 2.数字0 3.对象null ...
- C#实现简单的委托异步调用
delegate void textAsy(); static void Main(string[] args) { textAsy t = texts; AsyncCallback callBack ...
- 初学 react | redux
react | redux 一.安装 React Redux 依赖 React 0.14或更新版本 npm install --sava react-redux 你需要使用 npm 作为包管理工具,配 ...
- js汉语转拼音(全拼、首字母、拼音首字母)
新建js文件first_alphabet.js // JavaScript Document // 汉字拼音首字母列表 本列表包含了20902个汉字,用于配合 ToChineseSpell //函数使 ...