C#调用新浪微博API生成RSS资源文件

做者:一点一滴的Beer 我的主页:http://beer.cnblogs.comphp

新浪微博如今好像势头很猛,不少人在创立本身的微博客的时候,开始出于好奇,都会跟随不少人,长此以往,本身的好友人数超过100后,那么你就发现,你已经彻底淹没在信息的洪流中了,你跟随了那么多人,不少人都是从此可能永远都不会想起,也永远也不会看到的人,这显然与“关注”的目的是相背的,更有时候可能你只是想看下你认识的人的消息更新了没有,可是显然你不可能每次都一个个到本身的关注人物表中点开而后再一一访问他的主页,这样操做太繁琐了。html

用过RSS阅读器的用户可能都体会到RSS阅读器在获取信息的优越性了吧。它能实时跟踪RSS资源的更新,并显示更新数目到指定的订阅资源后面,可让用户有针对性地查看信息,让用户主动地去获取信息,而再也不是被动地接受信息了,这对于解决微博的“信息洪流”问题是颇有效的。node

笔者花费了几天时间,终于写了一个程序,用于获取指定用户的好友,并存储备份到ACCESS数据库中,而后生成一个RSS阅读资源。不敢独享,因此开源和你们分享。从此若是有时间,我想再将它作成一个桌面软件,方便通常不懂程序的用户来操做,这都是后话了吧。web

1. 新浪微博RSS订阅第三方网站数据库

新浪微博自己没有提供RSS订阅,可是到网上搜索,发现了一个第三方的网站,提供新浪微博的RSS资源,因此,本文的RSS订阅说白了都是基于这个第三方网站的。api

http://log.medcl.net/item/2010/02/sina-bo-rss-subscribe-feed-generate-micro/服务器

2. 网上通用的OPML文件的XML格式网络

下面是从Google Reader中导出的opml文件,这是网络RSS阅读器甚至全部RSS阅读器的标准格式吧,至少“鲜果”,“有道”这些比较流行的在线阅读器都支持这个格式的文件导入。架构

<?xml version="1.0" encoding="UTF-8"?><opml version="1.0">	<head><title>subscriptions</title><dateCreated>2010-05-16 15:45:03</dateCreated><ownerName></ownerName>	</head>	<body><outline text="微博客" title="微博客"><outline text="冷笑话(1567852087)"title="冷笑话(1567852087)" type="rss"htmlUrl="http://t.sina.com.cn/1567852087"xmlUrl="http://medcl.net/SinaRss.aspx?uid=1567852087" /><outline text="后宫优雅(1665289110)"title="后宫优雅(1665289110)" type="rss"htmlUrl="http://t.sina.com.cn/1665289110"xmlUrl="http://medcl.net/SinaRss.aspx?uid=1665289110" /><outline text="围脖经典语录"title="围脖经典语录" type="rss"htmlUrl="http://t.sina.com.cn/1646465281"xmlUrl="http://medcl.net/SinaRss.aspx?uid=1646465281" /><outline text="破阵子(1644022141)"title="破阵子(1644022141)" type="rss"htmlUrl="http://t.sina.com.cn/1644022141"xmlUrl="http://medcl.net/SinaRss.aspx?uid=1644022141" /></outline><outline text="珞珈山水" title="珞珈山水"><outline text="今日十大热门话题"title="今日十大热门话题" type="rss"htmlUrl="http://bbs.whu.edu.cn/frames.html"xmlUrl="http://bbs.whu.edu.cn/rssi.php?h=1" /><outline text="贴图版"title="贴图版" type="rss"htmlUrl="http://bbs.whu.edu.cn/wForum/board.php?name=Picture"xmlUrl="http://bbs.whu.edu.cn/wForum/rss.php?board=Picture&amp;ic=1" /></outline>	</body></opml>

 

分析OPML文件的架构,而后方便经过程序来将它须要的信息写成此架构的文件,便于阅读器引用。 OPML文件由头部标签<head>(主要是本文件的一些注释,不影响实际的RSS订阅信息,不是过重要)和<body>(RSS阅读器提取订阅资源的所有数据来源)。在<body>节点下面有个一级的<outline>节点,这个节点对应RSS阅读器中地RSS资源的分类文件夹相关信息(显然text表示的就是文件夹名称),而后一级<outline>下面就是二级的<outline>标签对,这里面就是RSS资源的相关数据内容了。二级<outline>中的节点的一些重要属性:text表示资源的标题,htmlUrl表示的是信息的的Web网页地址,xmlUrl表示的是信息的RSS订阅地址。dom

3. 新浪微博API――从服务器上导出用户好友数据到本地XML文件

关于新浪微博API的详细介绍,能够参考新浪微博API官方网站:

http://open.t.sina.com.cn/wiki/index.php/首页

关于身份认证和数据请求,请参考cnblogs:

《.NET调用新浪微博开放平台接口的代码示例》

http://www.cnblogs.com/cmt/archive/2010/05/13/1733904.html

下面是本身整理的代码,从服务器上请求用户的好友信息:

private void getFriends()        {            int previous_cursor=-1;            int next_cursor = -1;            while (next_cursor != 0)            {                string cursor = Convert.ToString(previous_cursor);                string url = " http://api.t.sina.com.cn/statuses/friends.xml?source=AppKey&cursor=" + cursor;                string username = "dreamzsm@gmail.com";                string password = name; //这里输入你本身微博登陆的的密码//注意这里的格式哦,为 "username:password"                System.Net.WebRequest webRequest = System.Net.WebRequest.Create(url);                System.Net.HttpWebRequest myReq = webRequest as System.Net.HttpWebRequest;                //身份验证string usernamePassword = username + ":" + password;                CredentialCache mycache = new CredentialCache();                mycache.Add(new Uri(url), "Basic", new NetworkCredential(username, password));                myReq.Credentials = mycache;                myReq.Headers.Add("Authorization", "Basic " + Convert.ToBase64String(new ASCIIEncoding().GetBytes(usernamePassword)));                WebResponse wr = myReq.GetResponse();                Stream receiveStream = wr.GetResponseStream();                StreamReader reader = new StreamReader(receiveStream, Encoding.UTF8);                string content = reader.ReadToEnd();                XmlDocument xmlDoc = new XmlDocument();                xmlDoc.LoadXml(content);                // xmlDoc.Load("data1.xml");                XmlNodeList nodeList = xmlDoc.SelectSingleNode("users").ChildNodes;//获取根节点的全部子节点                next_cursor = Convert.ToInt16(nodeList.Item(nodeList.Count - 2).InnerText);                previous_cursor = Convert.ToInt16(nodeList.Item(nodeList.Count-1).InnerText);                string xmlName = "friends_" + nodeList.Item(nodeList.Count - 1).InnerText + "_" + Convert.ToInt16(nodeList.Item(nodeList.Count - 2).InnerText) + ".xml";                previous_cursor = next_cursor;                xmlDoc.Save(xmlName);            }                  }

 

为了程序设计简单一点,笔者就有点偷懒了,没有仔细研究如何将全部的数据写到一个XML文件中,而是每次请求获得的20条数据写成一个XML文件,最后我159个好友,按照指定的命名方法生成了8个XML文件。

clip_image002

如此,就获得了全部的你的好友(就是你跟随的人)的信息了,以单人为例,其主要信息以下:

<user><id>1710993410</id><screen_name>某丫大人</screen_name><name>某丫大人</name><province>43</province><city>1</city><location>湖南 长沙</location><description>饭否儿,心朝饭否,春暖花开。 我仍是@饿YA 我还真是懒得介绍了。</description><url>http://1</url><profile_image_url>http://tp3.sinaimg.cn/1710993410/50/1273755892</profile_image_url><domain></domain><gender>f</gender><followers_count>168</followers_count><friends_count>79</friends_count><statuses_count>846</statuses_count><favourites_count>0</favourites_count><created_at>Sun Mar 14 00:00:00 +0800 2010</created_at><following>false</following><verified>false</verified><allow_all_act_msg>false</allow_all_act_msg><geo_enabled>false</geo_enabled><status><created_at>Sun May 16 21:02:44 +0800 2010</created_at><id>364379114</id><text>烦死了快、</text><source><a href="">新浪微博</a></source><favorited>false</favorited><truncated>false</truncated><geo /><in_reply_to_status_id></in_reply_to_status_id><in_reply_to_user_id></in_reply_to_user_id><in_reply_to_screen_name></in_reply_to_screen_name></status></user>

 

能够看到这里面的信息量是超级多的,我简单介绍下几个主要的节点吧

id

用户新浪微博的数字ID,就像你的QQ号同样

name

用户昵称

province

省代号

city

市代号

location

所在省市(好像和上面两个节点重复了)

description

自我描述

domain

域名,就是除了数字ID后,用户申请的修改域名

gender

性别。男的是Male,女的是Female.

followers_count

粉丝数

friends_count

跟随的人数

statuses_count

发表的状态也就是微博数

favourites_count

收藏微博数目吧?(不知道这个有什么用)

created_at

用户建立此微博客的时间

verified

是否通过新浪的VIP认证

status

用户最近的一次状态

除了user信息外,还有一些其它信息,好比根节点下的next_cursor和previous_cousor,这方便用户分屡次到服务器上请求数据时能够此做为定位依据。

<next_cursor>20</next_cursor>

<previous_cursor>0</previous_cursor>

4. 将XML文件存储到ACCESS数据库中进行备份

若是不想备份的能够直接从第3步中到第5步,可是笔者,以为将数据转换成此构架后,更加方便后来的程序操做以及浏览数据。

关于XML的详细方法参考:小气的鬼

在C#.net中如何操做XML

http://www.cnblogs.com/weekzero/archive/2005/06/21/178140.html

下面开始读取刚才重新浪微博服务器上请求获得的XML文件了。而后转换成ACCESS数据库内容。(固然你要先用ACCESS在指定目录下创建一个*.mdb文件用来存储数据)

下面是对单个XML文件进行读取,并插入到数据库中(这段代码是在ASP.NET中写的)

 public void readTsinaFriends(string fileName)    {        XmlDocument xmlDoc = new XmlDocument();        xmlDoc.Load(Server.MapPath(fileName));         XmlNodeList nodeList = xmlDoc.SelectSingleNode("users").ChildNodes;//获取 根节点的全部子节点       ;        //删除不用的一级节点,好比提示人数的所在位置的标记       XmlNode root = xmlDoc.SelectSingleNode("users");     //  XmlNodeList xnl = xmlDoc.SelectSingleNode("Employees").ChildNodes;for (int k = 0; k < nodeList.Count; k++)       {           XmlElement xe = (XmlElement)nodeList.Item(k);           if(xe.Name=="user")           {//去掉XML文件中不须要的节点:next_cursor,previous_coursor以及user节点中的status,方便XML直接转换成DataTable                XmlNodeList nodeList1 = xmlDoc.SelectNodes("users/user");//获得全部的标签user一级节点foreach (XmlNode xmlNodeTemp in nodeList1)                {                    if (xmlNodeTemp.LastChild.Name == "status")//移除每一个user节点中的"status"子节点--(通常状况下此节点都放在最后一个,因此就不遍历了,直接地址定位)                    {                        xmlNodeTemp.RemoveChild(xmlNodeTemp.LastChild);                    }                                }                                        }           else if (xe.Name == "next_cursor" || xe.Name == "previous_cursor")           {               root.RemoveChild(xe);               if (k < nodeList.Count) k = k - 1;           }       }        string tbxml = xmlDoc.OuterXml;        DataTable dt = new DataTable();        DataSet ds = new DataSet();        System.IO.StringReader reader = new System.IO.StringReader(tbxml);        ds.ReadXml(reader);        dt = ds.Tables[0];//若是XML文本中有同名的父子节点,那么此语句就会多读出一条数据,这多是此API函数的局限性吧        DataTable dtCopy = dt.Copy();        //dtCopy.Columns.Remove("url");//dtCopy.Columns.Remove("profile_image_url");        dtCopy.Columns.Remove("description"); //这个字段里面字符编码不太规则,在插入ACCESS的时候总有问题,并且用处不大,因此就去除了。(又偷懒了呃)        DataRow drTemp = dtCopy.NewRow();        string strInsert = string.Empty;        OleDbConnection aConnection = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=E:\\coursware\\网络软文\\API_微波\\weibo.mdb");        aConnection.Open();        for (int i = 0; i < dtCopy.Rows.Count - 1; i++)        {            drTemp = dtCopy.Rows[i];            strInsert = "'"+drTemp[0].ToString()+"','";            for (int j = 1; j < dtCopy.Columns.Count - 1; j++)            {                strInsert += (drTemp[j].ToString() + "','");            }            strInsert += drTemp[dtCopy.Columns.Count - 1].ToString() + "'";                       string strCmd = "INSERT INTO Friends VALUES(" + strInsert + ")";                        OleDbCommand command = new                OleDbCommand(strCmd, aConnection);            command.ExecuteNonQuery();        }        aConnection.Close();                             }

 

对多个XML文件进行遍历,一个个导入到ACCESS数据库中:

 /// <summary>/// 将全部好友都导出了,而后存储在ACCESS数据库中了。/// </summary>public void readAllXml()    {        for (int i = 0; i < 8; i++)        {            string fileName = "friends_" + Convert.ToString(i * 20) + "_" + Convert.ToString(i*20+20)+".xml";//按照存储XML文件时的命名规则进行读取            readTsinaFriends(fileName);        }    }

 

通过上面的操做后,你再打开你的ACCESS数据库文件weibo.mdb文件中对应的表,就能够看到因此的信息都已经导入到ACCESS中了。以下图所示:

clip_image004

5. 对ACCESS数据库查询并写成RSS阅读器的OPML格式

对于制做RSS阅读器的OPML格式,须要的数据只有两条字段:一个是id字段,一个是name字段。

这个过程实际上就是对数据进行XML编码的过程,啥都不说了,一切都在代码中了(也是在ASP.NET工程中写的):

/// <summary>/// 创建新浪微博的RSS文件/// </summary>public void CreateTsinaRssXmlFile()    {        OleDbConnection aConnection = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=E:\\coursware\\网络软文\\API_微波\\weibo.mdb");        string strCmd = "select id as idnum,screen_name as name from Friends";        //从ACCESS中获取数据        aConnection.Open();        OleDbDataAdapter da = new OleDbDataAdapter(strCmd, aConnection);        DataSet ds = new DataSet();        da.Fill(ds, "TSina");        ds.DataSetName = "RssReader";        DataTable dt = ds.Tables[0];//数据集的第0张表格        XmlDocument xmldoc;        XmlElement xmlelem;        xmldoc = new XmlDocument();        //加入XML的声明段落        XmlDeclaration xmldecl;        xmldecl = xmldoc.CreateXmlDeclaration("1.0", "UTF-8", null);        xmldoc.AppendChild(xmldecl);        //加入一个根元素        xmlelem = xmldoc.CreateElement(" ", "opml", " ");        xmldoc.AppendChild(xmlelem);        XmlNode root = xmldoc.SelectSingleNode("opml");//查找<opml> 节点        XmlElement xeHead = xmldoc.CreateElement("head");//建立一个<head>节点 //为head节点增长子节点        XmlElement xeHeadsub = xmldoc.CreateElement("title");        xeHeadsub.InnerText = "Rss Reader";//设置节点文本         xeHead.AppendChild(xeHeadsub);//添加到<head>子节点中         root.AppendChild(xeHead);//添加到<head>节点中 //增长body子节点,而后,将全部的RSS订阅信息所有写入到body节点中间        XmlElement xeBody = xmldoc.CreateElement("body");        root.AppendChild(xeBody);        //第一层循环是标签(文件夹循环)因为本次只作一个标签,因此就只循环一次了//RSS的文件夹属性节点        XmlElement xe1 = xmldoc.CreateElement("outline");        xe1.SetAttribute("text", "Tsina");//设置该节点title属性        xe1.SetAttribute("title", "Tsina");//设置该节点title属性 --第一层的outline节点的属性表示的是RSS的标签或者说是文件夹//下面就要开始为此文件夹节点添加下属子节点,也就是添加一些实质的RSS地址了string strTitle = string.Empty;        string strText = string.Empty;        string strXmlUrl = string.Empty;        string strHtmlUrl = string.Empty;        for (int i = 0; i < dt.Rows.Count; i++)        {            strTitle = dt.Rows[i]["NAME"].ToString().Trim();            strText = strTitle;            strXmlUrl = "http://medcl.net/SinaRss.aspx?uid=" + dt.Rows[i]["IDNum"].ToString().Trim();            strHtmlUrl = "http://t.sina.com.cn/" + dt.Rows[i]["IDNum"].ToString().Trim();            XmlElement xesub1 = xmldoc.CreateElement("outline");            xesub1.SetAttribute("text", strText);//设置该节点title属性            xesub1.SetAttribute("title", strTitle);//设置该节点title属性 --第一层的outline节点的属性表示的是RSS的标签或者说是文件夹            xesub1.SetAttribute("type", "rss");            xesub1.SetAttribute("xmlUrl", strXmlUrl);            xesub1.SetAttribute("htmlUrl", strHtmlUrl);            xe1.AppendChild(xesub1);//添加到<Node>节点中         }        xeBody.AppendChild(xe1);        //保存建立好的XML文档        xmldoc.Save(Server.MapPath("RssReader.xml"));    }

 

最后在指定的目录下,程序就自动生成了一个RssReader.xml的文件了。大功告成了!

clip_image006

而后将此文件就能够导入到任何一个RSS阅读器中了,用户就可以经过RSS阅读器来获取微博信息了,并且如今的RSS阅读器都有个一键转贴到微博的功能,很方便的,不想转到本身微博的,也能够经过RSS阅读器直接收藏到阅读器中。辛苦了两天,今天能有这么一点小成果,仍是以为很不错的,呵呵,也祝你们也能好运。本次代码比较还须要各类完善,好比,如何将因此的数据写成一个XML文件,这个笔者就暂时不作了,留给你们去作吧。

Rss阅读器效果图以下:

clip_image008

后记:新浪微博开放了API,今后新浪微博的可玩性就变强了不少了。写下本文主要是为了抛砖引玉,其实还有不少其它功能笔者想实现,但如今由于毕业在即,还要忙毕业设计,因此但愿你们能够试试,好比利用API来备份用户发的微博等等。

最后也写上本人的微博地址吧,若是有何指教,请留言:http://t.sina.com.cn/fly4u

相关文章
相关标签/搜索