- 帖子數量多,還沒看到就已經沉下去;
- 回帖速度快,無法及時獲得帖子狀態;
- 廣告比較多,看帖速度慢;
所以,我根據自己的使用習慣,用C#編寫了一個CSDN論壇閱讀器--Csdn Reader。
下面,我就來介紹一下它是如何編寫的。
一、 讀取帖子列表
由於不可能獲得網站後臺數據,我只能通過分析網頁的源代碼來得到需要的數據。爲了獲得最新的帖子列表,我使用了以下方法。
1. HttpWebRequest/ HttpWebResponse類
System.Net.HttpWebRequest和System.Net.HttpWebResponse類負責發送以及接收請求,使用戶能夠直接與使用 HTTP 的服務器交互。
例如,要獲得“.NET技術 ”
(http://community.csdn.net/Expert/ForumsList.asp?typenum=1&roomid=52)的源代碼,
首先,根據指定的網頁地址創建HttpWebRequest對象
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(URL);
然後,創建HttpWebResponse對象接收服務器要返回的信息,也就是源代碼,
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
最後,將獲取的信息讀取出來即可。
// encoding是網頁使用的編碼,不設置則爲默認值:UTF-8
System.IO.StreamReader sr = new System.IO.StreamReader(response.GetResponseStream(), encoding);
//讀取內容到字符串
string Html = sr.ReadToEnd();
2. 正則表達式
分析帖子列表的html源代碼,可以發現顯示帖子的html格式如下:
<a href="/Expert/TopicView1.asp?id=帖子ID" target="_blank">帖子標題</a>
</td>
<td align="right">用戶</td>
<td width="30" align="right">分數</td>
<td width="30" align="right">回覆</td>
<td width="80" align="right">時間</td>
這樣,就可以建立如下的正則表達式:
string strRegex =
@"<a[^<]*TopicView1.asp[^<]*id=(?<ID>[^<]*)""[^<]*target[^<]*>(?<topic>[^<]*)</a>[^<]*</td>[^<]*<td[^>]*>(?<user>[^<]*)</td>[^<]*<td[^>]*>(?<Points>[^<]*)</td>[^<]*<td[^>]*>(?<Replies>[^<]*)</td>[^<]*<td[^>]*>(?<ReplayTime>[^<]*)</td>";
小知識:什麼是正則表達式?
正則表達式,就是用某種模式去匹配一類字符串的一個公式。正則表達式提供了功能強大、靈活而又高效的方法來處理文本。正則表達式的全面模式匹配表示法可以快速分析大量文本以找到特定的字符模式;提取、編輯、替換或刪除文本子字符串;或將提取的字符串添加到集合以生成報告。
然後,通過Match對象就很容易得到帖子的相關信息。代碼如下:
Regex r;
MatchCollection m;
r = new Regex(strRegex, RegexOptions.IgnoreCase);
m = r.Matches(strHTML);
for (int i = 0; i < m.Count; i++)
{
Topic t = new Topic(m[i].Groups["ID"].Value
, m[i].Groups["topic"].Value
, m[i].Groups["user"].Value
, m[i].Groups["Points"].Value
, m[i].Groups["Replies"].Value
, m[i].Groups["ReplayTime"].Value);i
}
這裏,我建了一個Topic類去保存帖子的各項屬性,以方便對帖子列表顯示進行控制。比如對於新貼子用一個特別的圖標表示:
if (int.Parse(t.Replies) == 0)
item1.ImageKey = "NewTopic";
二、 看帖
打開任一帖子的html代碼,可以發現它實際上是一個XML文件,這時就需要使用XSLT。
小知識:什麼是XSLT ?
XSLT的英文標準名稱爲eXtensible Stylesheet Language Transformation(可擴展樣式表語言轉換)。XSLT可以將源 XML 文檔的內容轉換爲另一個格式或結構不同的文檔。
由於篇幅有限,這裏我就不具體介紹XSLT,其相關信息讀者可以查看MSDN。另外, VS.NET2005編輯器支持調試XSLT,可以隨時查看轉換效果。
調用XSL的代碼如下:
XmlDocument xml = new XmlDocument();
//加載帖子的XML源代碼
xml.LoadXml(strHTML);
XslCompiledTransform xslt = new XslCompiledTransform();
//加載XSLT
xslt.Load(Application.StartupPath.Replace(@"/", @"//") + @"//csdn.xsl");
//轉換後輸出到字符串
System.IO.StringWriter writer = new System.IO.StringWriter();
xslt.Transform(xml, null, writer);
strHtml = writer.ToString();
//最後將轉換後的HTML顯示到WebBrowser控件,IE爲控件名
this.IE.Document.Write(strHtml);
三、 回帖
看貼一定要回帖。同樣要使用HttpWebRequest/ HttpWebResponse類,但是這時是向服務器發送數據,需要在使用GetResponse創建HttpWebResponse對象之前先向HttpWebRequest對象寫入需要發送的數據,代碼如下:
//設置請求爲Post
request.ContentType = "application/x-www-form-urlencoded";
request.Method = "POST";
//將發送的數據轉換成byte數組
byte[] b = encoding.GetBytes(PostData);
//將數據寫入到HttpWebRequest對象
request.ContentLength = b.Length;
System.IO.Stream sw =request.GetRequestStream();
sw.Write(b, 0, b.Length);
sw.Close();
小結
這裏介紹的只是CSDN Reader的基本功能。讀者可以到http://feiyun0112.cnblogs.com/下載最新的源代碼。我會不斷的完善和更新,希望大家多提寶貴的意見和建議。
刊登於 電腦報2006年11月6日 第44期