网页抓取

简介: 之前做聊天室时,由于在聊天室中提供了新闻阅读的功能,写了一个从网页中抓取信息(如最新的头条新闻,新闻的来源,标题,内容等)的类,本文将介绍如何使用这个类来抓取网页中需要的信息。本文将以抓取博客园首页的博客标题和链接为例: 上图显示的是博客园首页的DOM树,显然只需提取出class为post_item的div,再重中提取出class为titlelnk的a标志即可。

之前做聊天室时,由于在聊天室中提供了新闻阅读的功能,写了一个从网页中抓取信息(如最新的头条新闻,新闻的来源,标题,内容等)的类,本文将介绍如何使用这个类来抓取网页中需要的信息。本文将以抓取博客园首页的博客标题和链接为例:

image

上图显示的是博客园首页的DOM树,显然只需提取出class为post_item的div,再重中提取出class为titlelnk的a标志即可。这样的功能可以通过以下函数来实现:

/// <summary>
/// 在文本html的文本查找标志名为tagName,并且属性attrName的值为attrValue的所有标志
/// 例如:FindTagByAttr(html, "div", "class", "demo")
/// 返回所有class为demo的div标志
/// </summary>
public static List<HtmlTag> FindTagByAttr(String html, String tagName, String attrName, String attrValue)
{
    String format = String.Format(@"<{0}\s[^<>]*{1}\s*=\s*(\x27|\x22){2}(\x27|\x22)[^<>]*>", tagName, attrName, attrValue);
    return FindTag(html, tagName, format);
}

public static List<HtmlTag> FindTag(String html, String name, String format)
{
    Regex reg = new Regex(format, RegexOptions.IgnoreCase);
    Regex tagReg = new Regex(String.Format(@"<(\/|)({0})(\s[^<>]*|)>", name), RegexOptions.IgnoreCase);

    List<HtmlTag> tags = new List<HtmlTag>();
    int start = 0;

    while (true)
    {
        Match match = reg.Match(html, start);
        if (match.Success)
        {
            start = match.Index + match.Length;
            Match tagMatch = null;
            int beginTagCount = 1;

            while (true)
            {
                tagMatch = tagReg.Match(html, start);
                if (!tagMatch.Success)
                {
                    tagMatch = null;
                    break;
                }
                start = tagMatch.Index + tagMatch.Length;
                if (tagMatch.Groups[1].Value == "/") beginTagCount--;
                else beginTagCount++;
                if (beginTagCount == 0) break;
            }

            if (tagMatch != null)
            {
                HtmlTag tag = new HtmlTag(name, match.Value, html.Substring(match.Index + match.Length, tagMatch.Index - match.Index - match.Length));
                tags.Add(tag);
            }
            else
            {
                break;
            }
        }
        else
        {
            break;
        }
    }

    return tags;
}

有了以上函数,就可以提取需要的HTML标志了,要实现抓取,还需要一个下载网页的函数:

public static String GetHtml(string url)
{
    try
    {
        HttpWebRequest req = HttpWebRequest.Create(url) as HttpWebRequest;
        req.Timeout = 30 * 1000;
        HttpWebResponse response = req.GetResponse() as HttpWebResponse;
        Stream stream = response.GetResponseStream();

        MemoryStream buffer = new MemoryStream();
        Byte[] temp = new Byte[4096];
        int count = 0;
        while ((count = stream.Read(temp, 0, 4096)) > 0)
        {
            buffer.Write(temp, 0, count);
        }

        return Encoding.GetEncoding(response.CharacterSet).GetString(buffer.GetBuffer());
    }
    catch
    {
        return String.Empty;
    }
}

以下以抓取博客园首页的文章标题和链接为例,介绍如何使用HtmlTag类来抓取网页信息:

class Program
{
    static void Main(string[] args)
    {
        String html = HtmlTag.GetHtml("http://www.cnblogs.com");
        List<HtmlTag> tags = HtmlTag.FindTagByAttr(html, "div", "id", "post_list");
        if (tags.Count > 0)
        {
            List<HtmlTag> item_tags = tags[0].FindTagByAttr("div", "class", "post_item");
            foreach (HtmlTag item_tag in item_tags)
            {
                List<HtmlTag> a_tags = item_tag.FindTagByAttr("a", "class", "titlelnk");
                if (a_tags.Count > 0)
                {
                    Console.WriteLine("标题:{0}", a_tags[0].InnerHTML);
                    Console.WriteLine("链接:{0}", a_tags[0].GetAttribute("href"));
                    Console.WriteLine("");
                }
            }
        }
    }
}

运行结果如下:

image

源代码下载

来源:http://www.cnblogs.com/lucc/archive/2010/05/18/1738718.html  

img_e00999465d1c2c1b02df587a3ec9c13d.jpg
微信公众号: 猿人谷
如果您认为阅读这篇博客让您有些收获,不妨点击一下右下角的【推荐】
如果您希望与我交流互动,欢迎关注微信公众号
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。

相关文章
|
XML 关系型数据库 MySQL
手把手教你在centos上配置Django项目(超详细步骤)
手把手教你在centos上配置Django项目(超详细步骤)
3107 0
手把手教你在centos上配置Django项目(超详细步骤)
|
10月前
|
存储 NoSQL Java
分布式session-SpringSession的应用
Spring Session 提供了一种创建和管理 Servlet HttpSession 的方案,默认使用外置 Redis 存储 Session 数据,解决 Session 共享问题。其主要特性包括:提供 API 和实现来管理用户会话,以中立方式替换应用程序容器中的 HttpSession,简化集群会话支持,并在单个浏览器实例中管理多个用户会话。此外,Spring Session 允许通过 headers 提供会话 ID 以使用 RESTful API。结合 Spring Boot 使用时,可通过配置 Redis 依赖和支持缓存的依赖实现 Session 共享。
199 0
分布式session-SpringSession的应用
|
28天前
|
JSON 中间件 Go
Go 网络编程:HTTP服务与客户端开发
Go 语言的 `net/http` 包功能强大,可快速构建高并发 HTTP 服务。本文从创建简单 HTTP 服务入手,逐步讲解请求与响应对象、URL 参数处理、自定义路由、JSON 接口、静态文件服务、中间件编写及 HTTPS 配置等内容。通过示例代码展示如何使用 `http.HandleFunc`、`http.ServeMux`、`http.Client` 等工具实现常见功能,帮助开发者掌握构建高效 Web 应用的核心技能。
164 61
|
8月前
「Mac畅玩鸿蒙与硬件32」UI互动应用篇9 - 番茄钟倒计时应用
本篇将带你实现一个番茄钟倒计时应用,用户可以设置专注时间和休息时间的时长,点击“开始专注”或“开始休息”按钮启动计时,应用会在倒计时结束时进行提醒。番茄钟应用对于管理时间、提升工作效率非常有帮助,并且还会加入猫咪图片作为界面装饰,让体验更加有趣。
257 8
「Mac畅玩鸿蒙与硬件32」UI互动应用篇9 - 番茄钟倒计时应用
|
SQL 监控 Oracle
|
机器学习/深度学习 算法 数据可视化
Python中的聚类分析以及如何使用Sklearn库进行聚类。
【4月更文挑战第20天】在Python的Scikit-learn库中进行聚类分析,包括安装库、导入模块、准备数据、选择算法(如K-means)、创建并训练模型、预测聚类、评估结果及可视化。
404 0
|
SQL 存储 Java
DBUtils工具类操作数据库
DButils工具类介绍
294 0
|
存储 区块链 Python
元宇宙宠物养殖游戏系统开发搭建-附源码部署示例
元宇宙宠物养殖游戏系统开发搭建-附源码部署示例