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

相關文章
相關標籤/搜索