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 = -1;
                                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 = -1;
                                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 > 0)
                        bir += birArr[0];
                    if (birArr.Length > 1)
                        bir += "-" + birArr[1];
                    if (birArr.Length > 2)
                        bir += "-" + birArr[2];
                }
                DateTime bDay = new DateTime(1900, 1, 1);
                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;
        }
    }
}

时间: 2024-10-28 15:26:59

HtmlAgilityPack组件的相关文章

从统计局抓取2016年最新的全国区县数据!!

using System; using System.Collections.Generic; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using HtmlAgilityPack; using System.Text; public partial class 抓取区县 : System.Web.UI.Page { protected void Page_Load(object sender,

快速抓取某个网站内容方法

是不是有人相抓取网页上面的内容,放到别的网站上面.下面我给大家介绍一种最常用的方法: 用HtmlAgilityPack 组件. public String GetHtml() { string url = "http://t.news.fx168.com/"; HttpWebRequest request = HttpWebRequest.Create(url) as HttpWebRequest; using (HttpWebResponse response = request.G

【原创】C#玩高频数字彩快3的一点体会

购彩风险非常高,本人纯属很久以前对数字高频彩的一点研究.目前已经远离数字彩,重点研究足球篮球比赛资料库和赛果预测. 这是一篇在草稿箱保存了1年多的文章,一直没发现,顺便修改修改分享给大家.以后会有更多关于足球和篮球体育彩票的玩法分析,希望大家关注. 本人不算专业程序员,但经常敲代码玩玩.上学时研究的是伪随机数这个东东,因此对彩票就情有独钟,从10年开始,就开始研究双色球,其中软件版本改了又改,但一直没有实际操作过,原因就是双色球的投注量太大.所以这1年多就没研究了.最近一次偶然的机会,发现了“高

老蜗牛写采集:网络爬虫(二)

短小精悍的xNet 这个一个俄国牛人写的开源工具,为啥说他强悍了,因为他将所有Http协议的底层都实现了一遍,这有啥好处?只要你是写爬虫的,都会遇到一个让人抓狂的问题,就是明明知道自己Http请求头跟浏览器一模一样了,为啥还会获取不到自己想要的数据.这时你如果使用HttpWebReaquest,你只能调试到GetRespone,底层的字节流是调试不到了.所以必须得有个更深入的底层组件,方便自己调试.以下是xNet的开源地址:https://github.com/X-rus/xNet快速入门 快速

从国家统计局官网获取最新省市区三级联动数据

目前从国家统计局官网找到的最新的县及县以上行政区划代码:http://www.stats.gov.cn/tjsj/tjbz/xzqhdm/201608/t20160809_1386477.html 可以看出省市区是有明显的缩进的,所以我们提取数据的时候可以从这个缩进做文章,下面开始分析页面: 查看页面dom结构,可以发现 北京市 市辖区 东城区 ,分别对应 省市区三个级别,他们前面的空格(其实不是空格,是一个特殊的空白符,为了方便就叫空格吧)数量是不一样的,我们就可以从空格数量判断出该数据的级别

使用C#和HtmlAgilityPack解析HTML

近期,有一个需求,需要解析HTML页面,读取一些需要的数据后,插入本地数据库.我知道可以通过正则表达式实现,然而正则表达式之于我,就像汇编语言之于我,一样.我知道它是干什么的,我也知道它能干什么,但是我一直不知道怎么干,曾经尝试过,后来用得太少,最终放弃了.也知道有一些组件可以实现操作HMTL,比如mshtml,比如WebBrowser,然而总是感觉不太好,不太专业.犹犹疑疑,一直没有开始,直到发现HtmlAgilityPack,如获至宝,中间那个词Agility,是敏捷.灵活的意思. 以下文字

C#+HtmlAgilityPack+XPath带你采集数据(以采集天气数据为例子)

转自原文C#+HtmlAgilityPack+XPath带你采集数据(以采集天气数据为例子) 阅读目录 1.HtmlAgilityPack简介 2.XPath技术介绍与使用 3.采集天气网站案例 4.资源 第一次接触HtmlAgilityPack是在5年前,一些意外,让我从技术部门临时调到销售部门,负责建立一些流程和寻找潜在客户,最后在阿里巴巴找到了很多客户信息,非常全面,刚开始是手动复制到Excel,是真尼玛的累,虽然那个时候C#还很菜,也想能不能通过程序来批量获取(所以平时想法要多才好).几

HtmlAgilityPack搭配 ScrapySharp或HtmlAgilityPack.CssSelectors

Html Agility Pack 源码中的类大概有28个左右,其实不算一个很复杂的类库,但它的功能确不弱,为解析DOM已经提供了足够强大的功能支持,可以跟jQuery操作DOM媲 美:)Html Agility Pack最常用的基础类其实不多,对解析DOM来说,就只有HtmlDocument和HtmlNode这两个常用的类,还有一个 HtmlNodeCollection集合类. 一.ScapySharp HTML Agility Pack的操作起来还是很麻烦,下面我们要介绍的这个组件是Scra

网络爬虫+HtmlAgilityPack+windows服务从博客园爬取20万博文

网络爬虫+HtmlAgilityPack+windows服务从博客园爬取20万博文 1.前言 最新在公司做一个项目,需要一些文章类的数据,当时就想到了用网络爬虫去一些技术性的网站爬一些,当然我经常去的就是博客园,于是就有下面的这篇文章. 2.准备工作 我需要把我从博客园爬取的数据,保存起来,最好的方式当然是保存到数据库中去了,好了我们先建一个数据库,在来一张表,保存我们的数据,其实都很简单的了啊,如下图所示 BlogArticleId博文自增ID,BlogTitle博文标题,BlogUrl博文地