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, ...
随机推荐
- Java处理Excel整理篇
常用Excel,每次写的时候都得现查,索性做一个整理. Java里用的时候一般用jxl这个包,相对好用. 读: File file = new File(excelFile);Workbook boo ...
- 5.Struts2中的拦截器
拦截器是Struts2中的核心,其自带很多很多的拦截器,这里主要介绍一下自定义拦截器,恩多一半情况下呢?我们不需要使用到自定义的拦截器,Struts2本身已经提 供了很多的拦截器供我们使用,对于自定义 ...
- scala变量
#声明与定义(赋值) val 常量声明 val x:T val x:T=e (x:名字,T:类型,e:值) var 变量声明 var x:T var x:T=e #类型省略(默认类型) v ...
- 【面向对象版】HashMap(增删改查)
前言: 关于什么是HashMap,HashMap可以用来做些什么,这些定义类的描述,请参照[简易版]HashMap(增删改查)的内容. 这章节主要是面向实例,直接进行HashMap(增删改查)的演示. ...
- CC1310之使用SMARTRF STUDIO
SMARTRF STUDIO是TI提供的射频测试软件,在调射频的时候非常非常非常好用,推荐每一个使用TI射频芯片的工程师都要掌握. 1 如何使用? 要使用SMARTRF STUDIO,硬件必须连接仿真 ...
- PowerDesigner 16.5 反向PostgreSQL9.01 中 Unable to list the columns. SQLSTATE = 22003不良的类型值 short : t 解决方法
Database➙Edit Current DBMS… General tab➙PostgreSQL 9.x➙Script➙Objects➙Column➙SqlListQuery or Tools➙R ...
- java序列化深拷贝
java深拷贝 序列化和反序列化合成在一起的方法CloneUtils import java.io.ByteArrayInputStream; import java.io.ByteArrayOutp ...
- Java基础---AWT
流式布局FlowLayout package net.zyz; import java.awt.Button; import java.awt.FlowLayout; import java.awt. ...
- allegro - 层叠相关参数
层叠结构设置 弹出Layout Cross Section对话框 Subclass Name一列是该层的名称,可以按照自己的需要来填写.Type 列选择该层的类型,有三种: ·CONDUCTOR: ...
- C语言字符串拷贝
C语言字符串拷贝利用指针操作,要清楚知道指针的指向 代码如下: #include <stdio.h> #include <assert.h> #include <stri ...