今天,有位群友问我如何获新浪新闻列表相关问题,我想,用正则表达式网页中取显然既复杂又不一定准确,现在许多大型网站都有RSS集合,所以我就跟他说用RSS应该好办一些。

一年前我写过一个RSS阅读器,不过,打新浪相关的XML文件看了一下,发现RSS2.0 和一年前的不大一样了,但具体怎么处理,几句话也很难讲得清楚,所以,我干脆写了一个类库给他,直接调用。

类库不是很复杂,主要两个功能:

一、通过新浪的根频道XML在把所有频道的信息读出来,使用递归连同子节点也读取出来。

二、指定频道URL的XML文件来获取新闻信息。

首先,我们写两个类,一个用于保存新闻个息,另一个用于保存频道信息。

  1. /// <summary>
  2. /// 新闻记录实体
  3. /// </summary>
  4. [Serializable]
  5. public  class NewsItem
  6. {
  7. /// <summary>
  8. /// 新闻标题
  9. /// </summary>
  10. public string Title { get; set; }
  11. /// <summary>
  12. /// 新闻链接
  13. /// </summary>
  14. public string Link { get; set; }
  15. /// <summary>
  16. /// 作者
  17. /// </summary>
  18. public string Author { get; set; }
  19. /// <summary>
  20. /// 分类
  21. /// </summary>
  22. public string Category { get; set; }
  23. /// <summary>
  24. /// 发布时间
  25. /// </summary>
  26. public DateTime PubDate { get; set; }
  27. /// <summary>
  28. /// 描述
  29. /// </summary>
  30. public string Description { get; set; }
  31. /// <summary>
  32. /// 其它说明
  33. /// </summary>
  34. public string Comments { get; set; }
  35. }
  1. /// <summary>
  2. /// 新闻频道列表
  3. /// </summary>
  4. [Serializable]
  5. public  class OutLine
  6. {
  7. /// <summary>
  8. /// 频道标题
  9. /// </summary>
  10. public string Title { get; set; }
  11. /// <summary>
  12. /// 频道文本
  13. /// </summary>
  14. public string Text { get; set; }
  15. /// <summary>
  16. /// 频道类型-RSS
  17. /// </summary>
  18. public string Type { get; set; }
  19. /// <summary>
  20. /// XML地址
  21. /// </summary>
  22. public string xmlUrl { get; set; }
  23. /// <summary>
  24. /// HTML地址
  25. /// </summary>
  26. public string htmlUrl { get; set; }
  27. private List<OutLine> _olChildren = new List<OutLine>();
  28. /// <summary>
  29. /// 子频道
  30. /// </summary>
  31. public List<OutLine> ChildrenOutline
  32. {
  33. get { return _olChildren; }
  34. }
  35. }

好,接下来对应的两类,分别获取频道列表和新闻列表。

  1. /// <summary>
  2. /// 新闻项管理类
  3. /// </summary>
  4. public class NewsManager
  5. {
  6. /// <summary>
  7. /// 根据输入的XML地址获取新闻列表。
  8. /// </summary>
  9. /// <param name="xmlUrl">新闻频道的XML地址</param>
  10. /// <returns>NewsItem的结果集合</returns>
  11. public List<NewsItem> GetNewsItemList(string xmlUrl)
  12. {
  13. List<NewsItem> _myNews = new List<NewsItem>();
  14. XElement myRoot = XElement.Load(xmlUrl);
  15. var theItems =
  16. from xe in myRoot.Element("channel").Elements("item")
  17. select xe;
  18. foreach (XElement e in theItems)
  19. {
  20. _myNews.Add(new NewsItem()
  21. {
  22. Title = (string)e.Element("title"),
  23. Link = (string)e.Element("link"),
  24. Author = (string)e.Element("author"),
  25. Category = (string)e.Element("category"),
  26. PubDate = (DateTime)e.Element("pubDate"),
  27. Comments = (string)e.Element("comments"),
  28. Description = (string)e.Element("description")
  29. });
  30. }
  31. return _myNews;
  32. }
  33. }
  1. /// <summary>
  2. /// 自动获取频道列表类
  3. /// </summary>
  4. public class OutlineManager
  5. {
  6. /// <summary>
  7. /// 获取频道列表,包含子节点
  8. /// </summary>
  9. /// <param name="xmlUrl">根频道地址</param>
  10. /// <returns></returns>
  11. public List<OutLine> GetCannels(string xmlUrl)
  12. {
  13. List<OutLine> _list = new List<OutLine>();
  14. XElement root = XElement.Load(xmlUrl);
  15. var firstOutline = root.Element("body").Elements("outline");
  16. foreach (XElement xitem in firstOutline)
  17. {
  18. OutLine myRootOutline = new OutLine
  19. {
  20. Title = (string)xitem.Attribute("title") ?? "",
  21. Text = (string)xitem.Attribute("text") ?? "",
  22. Type = (string)xitem.Attribute("type") ?? "",
  23. xmlUrl = (string)xitem.Attribute("xmlUrl") ?? "",
  24. htmlUrl = (string)xitem.Attribute("htmlUrl") ?? ""
  25. };
  26. AddChildElements(xitem, myRootOutline);
  27. _list.Add(myRootOutline);
  28. }
  29. return _list;
  30. }
  31. private void AddChildElements(XElement xNode, OutLine ol)
  32. {
  33. if (xNode == null) return;
  34. var xc = xNode.Elements("outline");
  35. // 递归,添加子节点
  36. foreach (XElement xe in xc)
  37. {
  38. OutLine outline = new OutLine()
  39. {
  40. Title = xe.Attribute("title").Value,
  41. Text = xe.Attribute("text").Value,
  42. Type = xe.Attribute("type").Value,
  43. xmlUrl = xe.Attribute("xmlUrl").Value,
  44. htmlUrl = xe.Attribute("htmlUrl").Value
  45. };
  46. ol.ChildrenOutline.Add(outline);
  47. AddChildElements(xe, outline);
  48. }
  49. }
  50. }

OK,简单的类库写好了,程序集名称为SinaRssAPIs_CS,然后,我们建一个程序来测试一下。

  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Data;
  5. using System.Drawing;
  6. using System.Linq;
  7. using System.Text;
  8. using System.Windows.Forms;
  9. using SinaRssAPIs_CS;
  10. namespace NewsApiTest
  11. {
  12. public partial class Form1 : Form
  13. {
  14. public Form1()
  15. {
  16. InitializeComponent();
  17. this.WindowState = FormWindowState.Maximized;
  18. this.Text = "新浪RSS类库示例程序";
  19. this.treeView1.AfterSelect += new TreeViewEventHandler(treeView1_AfterSelect);
  20. this.dataGridView1.AutoGenerateColumns = false; //不自动创建列
  21. //添加列
  22. DataGridViewTextBoxColumn colTitle = new DataGridViewTextBoxColumn();
  23. colTitle.HeaderText = "新闻标题";
  24. colTitle.DataPropertyName = "Title";
  25. this.dataGridView1.Columns.Add(colTitle);
  26. DataGridViewTextBoxColumn colDesc = new DataGridViewTextBoxColumn();
  27. colDesc.HeaderText = "描述";
  28. colDesc.DataPropertyName = "Description";
  29. colDesc.Width = 280;
  30. this.dataGridView1.Columns.Add(colDesc);
  31. DataGridViewTextBoxColumn colDate = new DataGridViewTextBoxColumn();
  32. colDate.DefaultCellStyle.Format = "yyyy-MM-dd";
  33. colDate.HeaderText = "发布日期";
  34. colDate.DataPropertyName = "PubDate";
  35. this.dataGridView1.Columns.Add(colDate);
  36. DataGridViewTextBoxColumn colAuthor = new DataGridViewTextBoxColumn();
  37. colAuthor.HeaderText = "发布者";
  38. colAuthor.DataPropertyName = "Author";
  39. this.dataGridView1.Columns.Add(colAuthor);
  40. DataGridViewTextBoxColumn colLink = new DataGridViewTextBoxColumn();
  41. colLink.DataPropertyName = "Link";
  42. colLink.Name = "link";
  43. colLink.Visible = false;
  44. this.dataGridView1.Columns.Add(colLink);
  45. this.dataGridView1.SelectionChanged += new EventHandler(dataGridView1_SelectionChanged);
  46. }
  47. void dataGridView1_SelectionChanged(object sender, EventArgs e)
  48. {
  49. if (this.dataGridView1.CurrentRow == null) return;
  50. string link = this.dataGridView1.CurrentRow.Cells["link"].Value.ToString();
  51. this.webBrowser1.Navigate(link);
  52. }
  53. void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
  54. {
  55. if (e.Node.Tag == null) return;
  56. string xml = e.Node.Tag.ToString();
  57. List<NewsItem> items = null;
  58. NewsManager mg = new NewsManager();
  59. items = mg.GetNewsItemList(xml);
  60. this.dataGridView1.DataSource = items;
  61. }
  62. private void Form1_Load(object sender, EventArgs e)
  63. {
  64. OutlineManager omg = new OutlineManager();
  65. List<OutLine> cnList = omg.GetCannels(@"http://rss.sina.com.cn/sina_all_opml.xml");
  66. this.treeView1.BeginUpdate();
  67. this.treeView1.Nodes.Clear();
  68. //根节点
  69. foreach (OutLine  root in cnList)
  70. {
  71. TreeNode tnRoot = new TreeNode();
  72. tnRoot.Text = root.Title.Split('-')[0];
  73. AddNodes(root, tnRoot);
  74. this.treeView1.Nodes.Add(tnRoot);
  75. }
  76. this.treeView1.EndUpdate();
  77. }
  78. private void AddNodes(OutLine ol, TreeNode nd)
  79. {
  80. foreach (OutLine oits in ol.ChildrenOutline)
  81. {
  82. TreeNode tn = new TreeNode();
  83. tn.Text = oits.Title;
  84. tn.Tag = oits.xmlUrl;
  85. AddNodes(oits, tn);
  86. nd.Nodes.Add(tn);
  87. }
  88. }
  89. }
  90. }

大致的运行效果如下:

现在,我说一下技术要点,不多,就一个,对,就是LinQ To XML。

今天写了一个简单的新浪新闻RSS操作类库的更多相关文章

  1. 自己写的一个简单PHP采集器

    自己写的一个简单PHP采集器 <?php //**************************************************************** $url = &q ...

  2. 只是一个用EF写的一个简单的分页方法而已

    只是一个用EF写的一个简单的分页方法而已 慢慢的写吧.比如,第一步,先把所有数据查询出来吧. //第一步. public IQueryable<UserInfo> LoadPagesFor ...

  3. 写了一个简单的CGI Server

    之前看过一些开源程序的源码,也略微知道些Apache的CGI处理程序架构,于是用了一周时间,用C写了一个简单的CGI Server,代码算上头文件,一共1200行左右,难度中等偏上,小伙伴可以仔细看看 ...

  4. 写了一个简单可用的IOC

    根据<架构探险从零开始写javaweb框架>内容写的一个简单的 IOC 学习记录    只说明了主要的类,从上到下执行的流程,需要分清主次,无法每个类都说明,只是把整个主线流程说清楚,避免 ...

  5. 写了一个简单的 Mybatis

    写了一个简单的 Mybatis,取名 SimpleMybatis . 具备增删改查的基本功能,后续还要添加剩下的基本数据类型和Java集合类型的处理. 脑图中有完整的源码和测试的地址 http://n ...

  6. 门户级UGC系统的技术进化路线——新浪新闻评论系统的架构演进和经验总结(转)

    add by zhj:先收藏了 摘要:评论系统是所有门户网站的核心标准服务组件之一.本文作者曾负责新浪网评论系统多年,这套系统不仅服务于门户新闻业务,还包括调查.投票等产品,经历了从单机到多机再到集群 ...

  7. Python爬虫:新浪新闻详情页的数据抓取(函数版)

    上一篇文章<Python爬虫:抓取新浪新闻数据>详细解说了如何抓取新浪新闻详情页的相关数据,但代码的构建不利于后续扩展,每次抓取新的详情页时都需要重新写一遍,因此,我们需要将其整理成函数, ...

  8. 采集新浪新闻php插件

    今天没事,就分享一个采集新浪新闻PHP插件接口,可用于火车头采集,比较简单,大家可以研究! 新浪新闻实时动态列表为:https://news.sina.com.cn/roll/?qq-pf-to=pc ...

  9. Lance老师UI系列教程第八课->新浪新闻SlidingMenu界面的实现

    UI系列教程第八课:Lance老师UI系列教程第八课->新浪新闻SlidingMenu界面的实现 今天蓝老师要讲的是关于新浪新闻侧滑界面的实现.先看看原图: 如图所示,这种侧滑效果以另一种方式替 ...

随机推荐

  1. AppFuse 3常见问题与解决方法

    非常长一段时间没做SSH项目了.近期抽出时间看了一下升级到3.x的appfuse,对新版本号使用过程中出现的一些问题进行了排查.汇总例如以下.以备后用.本文原文出处: http://blog.csdn ...

  2. jenkins集成多个项目

    https://www.cnblogs.com/gossip/p/5961376.html 需要jenkins版本高点 安装插件:Multijob plugin

  3. 黑马程序猿——————java基础

    一.软件开发 软件是什么? 软件是简单的来说,计算机数据和指令的集合,数据(比方年龄,性别).指令及时告诉计算机怎样对他进行处理.计算机但是没有人那么聪明啊! 二.图形化界面(GUI),主要特点就是. ...

  4. 为什么倒排索引不采用zlib这样的字典压缩算法——因为没法直接使用啊

    看了下压缩算法的发展历史,根据倒排索引的数据结构特点,个人认为zstd不适合做倒排索引压缩,举例说明下: 假设有一份文档倒排列表为:[300, 302, 303, 332],对于这组倒排数据,是没法* ...

  5. Codeforces--630J--Divisibility(公倍数)

     J - Divisibility Crawling in process... Crawling failed Time Limit:500MS     Memory Limit:65536KB ...

  6. poj3071Football(概率期望dp)

    Football Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 5620   Accepted: 2868 Descript ...

  7. go的语言结构

    一.文件名.关键字与标识符 1.1 文件名 1.go 的源文件已 .go 为后缀名 2.文件名已小写组成 如:simple.go 3.如多个部分组成可用"_" 分割 4.不要包含有 ...

  8. html中canvas渲染图片,并转化成base64格式保存

    最近在做一个上传头像然后保存显示的功能,因为涉及到裁剪大小和尺寸比例,所以直接上传图片再展示的话,就会出现问题,所以就想用canvas来渲染裁剪后的图片,然后转化成base64格式的图片再存储,这样取 ...

  9. 前端-Vue学习思维导图笔记

    看不清的朋友右键保存或者新窗口打开哦!喜欢我可以关注我,还有更多前端思维导图笔记有vue结构分析,JS基础,JQ,JS高级,Angular,git等等

  10. RecyclerView的基础用法

    为了让RecyclerView可以在所有的Android版本中都能使用,Android开发团队将RecyclerView定义在support.v7包当中.在使用该控件时需要打开当前Modile的bui ...