今天写了一个简单的新浪新闻RSS操作类库

2024-03-20 01:38

本文主要是介绍今天写了一个简单的新浪新闻RSS操作类库,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

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

 

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

 

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

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

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

 

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

    /// <summary>
/// 新闻记录实体
/// </summary>
[Serializable]
public  class NewsItem
{
/// <summary>
/// 新闻标题
/// </summary>
public string Title { get; set; }
/// <summary>
/// 新闻链接
/// </summary>
public string Link { get; set; }
/// <summary>
/// 作者
/// </summary>
public string Author { get; set; }
/// <summary>
/// 分类
/// </summary>
public string Category { get; set; }
/// <summary>
/// 发布时间
/// </summary>
public DateTime PubDate { get; set; }
/// <summary>
/// 描述
/// </summary>
public string Description { get; set; }
/// <summary>
/// 其它说明
/// </summary>
public string Comments { get; set; }
}


 

    /// <summary>
/// 新闻频道列表 
/// </summary>
[Serializable]
public  class OutLine
{
/// <summary>
/// 频道标题
/// </summary>
public string Title { get; set; }
/// <summary>
/// 频道文本
/// </summary>
public string Text { get; set; }
/// <summary>
/// 频道类型-RSS
/// </summary>
public string Type { get; set; }
/// <summary>
/// XML地址
/// </summary>
public string xmlUrl { get; set; }
/// <summary>
/// HTML地址
/// </summary>
public string htmlUrl { get; set; }
private List<OutLine> _olChildren = new List<OutLine>();
/// <summary>
/// 子频道
/// </summary>
public List<OutLine> ChildrenOutline
{
get { return _olChildren; }
}
}


 

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

    /// <summary>
/// 新闻项管理类
/// </summary>
public class NewsManager
{
/// <summary>
/// 根据输入的XML地址获取新闻列表。
/// </summary>
/// <param name="xmlUrl">新闻频道的XML地址</param>
/// <returns>NewsItem的结果集合</returns>
public List<NewsItem> GetNewsItemList(string xmlUrl)
{
List<NewsItem> _myNews = new List<NewsItem>();
XElement myRoot = XElement.Load(xmlUrl);
var theItems =
from xe in myRoot.Element("channel").Elements("item")
select xe;
foreach (XElement e in theItems)
{
_myNews.Add(new NewsItem()
{
Title = (string)e.Element("title"),
Link = (string)e.Element("link"),
Author = (string)e.Element("author"),
Category = (string)e.Element("category"),
PubDate = (DateTime)e.Element("pubDate"),
Comments = (string)e.Element("comments"),
Description = (string)e.Element("description")
});
}
return _myNews;
}
}


 

    /// <summary>
/// 自动获取频道列表类
/// </summary>
public class OutlineManager
{
/// <summary>
/// 获取频道列表,包含子节点
/// </summary>
/// <param name="xmlUrl">根频道地址</param>
/// <returns></returns>
public List<OutLine> GetCannels(string xmlUrl)
{
List<OutLine> _list = new List<OutLine>();
XElement root = XElement.Load(xmlUrl);
var firstOutline = root.Element("body").Elements("outline");
foreach (XElement xitem in firstOutline)
{
OutLine myRootOutline = new OutLine
{
Title = (string)xitem.Attribute("title") ?? "",
Text = (string)xitem.Attribute("text") ?? "",
Type = (string)xitem.Attribute("type") ?? "",
xmlUrl = (string)xitem.Attribute("xmlUrl") ?? "",
htmlUrl = (string)xitem.Attribute("htmlUrl") ?? ""
};
AddChildElements(xitem, myRootOutline);
_list.Add(myRootOutline);
}
return _list;
}
private void AddChildElements(XElement xNode, OutLine ol)
{
if (xNode == null) return;
var xc = xNode.Elements("outline");
// 递归,添加子节点
foreach (XElement xe in xc)
{
OutLine outline = new OutLine()
{
Title = xe.Attribute("title").Value,
Text = xe.Attribute("text").Value,
Type = xe.Attribute("type").Value,
xmlUrl = xe.Attribute("xmlUrl").Value,
htmlUrl = xe.Attribute("htmlUrl").Value
};
ol.ChildrenOutline.Add(outline);
AddChildElements(xe, outline);
}
}
}


 

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

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using SinaRssAPIs_CS;
namespace NewsApiTest
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.WindowState = FormWindowState.Maximized;
this.Text = "新浪RSS类库示例程序";
this.treeView1.AfterSelect += new TreeViewEventHandler(treeView1_AfterSelect);
this.dataGridView1.AutoGenerateColumns = false; //不自动创建列
//添加列
DataGridViewTextBoxColumn colTitle = new DataGridViewTextBoxColumn();
colTitle.HeaderText = "新闻标题";
colTitle.DataPropertyName = "Title";
this.dataGridView1.Columns.Add(colTitle);
DataGridViewTextBoxColumn colDesc = new DataGridViewTextBoxColumn();
colDesc.HeaderText = "描述";
colDesc.DataPropertyName = "Description";
colDesc.Width = 280;
this.dataGridView1.Columns.Add(colDesc);
DataGridViewTextBoxColumn colDate = new DataGridViewTextBoxColumn();
colDate.DefaultCellStyle.Format = "yyyy-MM-dd";
colDate.HeaderText = "发布日期";
colDate.DataPropertyName = "PubDate";
this.dataGridView1.Columns.Add(colDate);
DataGridViewTextBoxColumn colAuthor = new DataGridViewTextBoxColumn();
colAuthor.HeaderText = "发布者";
colAuthor.DataPropertyName = "Author";
this.dataGridView1.Columns.Add(colAuthor);
DataGridViewTextBoxColumn colLink = new DataGridViewTextBoxColumn();
colLink.DataPropertyName = "Link";
colLink.Name = "link";
colLink.Visible = false;
this.dataGridView1.Columns.Add(colLink);
this.dataGridView1.SelectionChanged += new EventHandler(dataGridView1_SelectionChanged);
}
void dataGridView1_SelectionChanged(object sender, EventArgs e)
{
if (this.dataGridView1.CurrentRow == null) return;
string link = this.dataGridView1.CurrentRow.Cells["link"].Value.ToString();
this.webBrowser1.Navigate(link);
}
void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
{
if (e.Node.Tag == null) return;
string xml = e.Node.Tag.ToString();
List<NewsItem> items = null;
NewsManager mg = new NewsManager();
items = mg.GetNewsItemList(xml);
this.dataGridView1.DataSource = items;
}
private void Form1_Load(object sender, EventArgs e)
{
OutlineManager omg = new OutlineManager();
List<OutLine> cnList = omg.GetCannels(@"http://rss.sina.com.cn/sina_all_opml.xml");
this.treeView1.BeginUpdate();
this.treeView1.Nodes.Clear();
//根节点
foreach (OutLine  root in cnList)
{
TreeNode tnRoot = new TreeNode();
tnRoot.Text = root.Title.Split('-')[0];
AddNodes(root, tnRoot);
this.treeView1.Nodes.Add(tnRoot);
}
this.treeView1.EndUpdate();
}
private void AddNodes(OutLine ol, TreeNode nd)
{
foreach (OutLine oits in ol.ChildrenOutline)
{
TreeNode tn = new TreeNode();
tn.Text = oits.Title;
tn.Tag = oits.xmlUrl;
AddNodes(oits, tn);
nd.Nodes.Add(tn);
}
}
}
}


大致的运行效果如下:

 

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

这篇关于今天写了一个简单的新浪新闻RSS操作类库的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/827897

相关文章

csu 1446 Problem J Modified LCS (扩展欧几里得算法的简单应用)

这是一道扩展欧几里得算法的简单应用题,这题是在湖南多校训练赛中队友ac的一道题,在比赛之后请教了队友,然后自己把它a掉 这也是自己独自做扩展欧几里得算法的题目 题意:把题意转变下就变成了:求d1*x - d2*y = f2 - f1的解,很明显用exgcd来解 下面介绍一下exgcd的一些知识点:求ax + by = c的解 一、首先求ax + by = gcd(a,b)的解 这个

hdu2289(简单二分)

虽说是简单二分,但是我还是wa死了  题意:已知圆台的体积,求高度 首先要知道圆台体积怎么求:设上下底的半径分别为r1,r2,高为h,V = PI*(r1*r1+r1*r2+r2*r2)*h/3 然后以h进行二分 代码如下: #include<iostream>#include<algorithm>#include<cstring>#include<stack>#includ

usaco 1.3 Prime Cryptarithm(简单哈希表暴搜剪枝)

思路: 1. 用一个 hash[ ] 数组存放输入的数字,令 hash[ tmp ]=1 。 2. 一个自定义函数 check( ) ,检查各位是否为输入的数字。 3. 暴搜。第一行数从 100到999,第二行数从 10到99。 4. 剪枝。 代码: /*ID: who jayLANG: C++TASK: crypt1*/#include<stdio.h>bool h

uva 10387 Billiard(简单几何)

题意是一个球从矩形的中点出发,告诉你小球与矩形两条边的碰撞次数与小球回到原点的时间,求小球出发时的角度和小球的速度。 简单的几何问题,小球每与竖边碰撞一次,向右扩展一个相同的矩形;每与横边碰撞一次,向上扩展一个相同的矩形。 可以发现,扩展矩形的路径和在当前矩形中的每一段路径相同,当小球回到出发点时,一条直线的路径刚好经过最后一个扩展矩形的中心点。 最后扩展的路径和横边竖边恰好组成一个直

poj 1113 凸包+简单几何计算

题意: 给N个平面上的点,现在要在离点外L米处建城墙,使得城墙把所有点都包含进去且城墙的长度最短。 解析: 韬哥出的某次训练赛上A出的第一道计算几何,算是大水题吧。 用convexhull算法把凸包求出来,然后加加减减就A了。 计算见下图: 好久没玩画图了啊好开心。 代码: #include <iostream>#include <cstdio>#inclu

uva 10130 简单背包

题意: 背包和 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#include <stack>#include <vector>#include <queue>#include <map>

Vue3项目开发——新闻发布管理系统(六)

文章目录 八、首页设计开发1、页面设计2、登录访问拦截实现3、用户基本信息显示①封装用户基本信息获取接口②用户基本信息存储③用户基本信息调用④用户基本信息动态渲染 4、退出功能实现①注册点击事件②添加退出功能③数据清理 5、代码下载 八、首页设计开发 登录成功后,系统就进入了首页。接下来,也就进行首页的开发了。 1、页面设计 系统页面主要分为三部分,左侧为系统的菜单栏,右侧

动手学深度学习【数据操作+数据预处理】

import osos.makedirs(os.path.join('.', 'data'), exist_ok=True)data_file = os.path.join('.', 'data', 'house_tiny.csv')with open(data_file, 'w') as f:f.write('NumRooms,Alley,Price\n') # 列名f.write('NA

线程的四种操作

所属专栏:Java学习        1. 线程的开启 start和run的区别: run:描述了线程要执行的任务,也可以称为线程的入口 start:调用系统函数,真正的在系统内核中创建线程(创建PCB,加入到链表中),此处的start会根据不同的系统,分别调用不同的api,创建好之后的线程,再单独去执行run(所以说,start的本质是调用系统api,系统的api

JAVA用最简单的方法来构建一个高可用的服务端,提升系统可用性

一、什么是提升系统的高可用性 JAVA服务端,顾名思义就是23体验网为用户提供服务的。停工时间,就是不能向用户提供服务的时间。高可用,就是系统具有高度可用性,尽量减少停工时间。如何用最简单的方法来搭建一个高效率可用的服务端JAVA呢? 停工的原因一般有: 服务器故障。例如服务器宕机,服务器网络出现问题,机房或者机架出现问题等;访问量急剧上升,导致服务器压力过大导致访问量急剧上升的原因;时间和