iT邦幫忙

DAY 2
6

c#應用系列 第 2

C#應用(2)取得台灣天氣資料

取得中央氣象局的各地天氣資料
相關技術:
*WebRequestHttpWebRequestHttpWebResponse
*FtpWebRequestFtpWebResponse
*RegexMatch
*XmlDocumentXmlNodeList

回目錄
*檔案 InternetClient.cs
這個是多年前寫的, 那時大約還是.NET Framework 2.0的時代
後來在 2011年10月17日於個人網站上OpenSource
(在這之前的版本是2007年8月21日OpenSource的HttpClient.cs?)
因為直接從HTTP或FTP上抓回來的內容, 會因為他們輸出的編碼設定不同, 而變亂碼
因此加上指定語系的方式, 以取得正確的內容

using System;
using System.Web;
using System.IO;
using System.Net;
using System.Text;
using System.Collections.Generic;  
 
/// <summary>
/// InternetClient 的摘要描述
/// </summary>
public class InternetClient
{
    public static string UserID = string.Empty;     //連線驗證用的帳號
    public static string Password = string.Empty;   //連線驗證用的密碼
    public static bool KeepAlive = false;   //是否保持連線
    public static int Timeout = 10000;      //預設TimeOut=10秒

#region Http
    public static string HttpGet(string strUrl)
	{
		return InternetClient.HttpGet(strUrl, System.Text.Encoding.Default);
	}
 
	public static string HttpGet(string strUrl, Encoding TextEncoding)
	{
		string strRet = "";
		Uri uri = new Uri(strUrl);
		HttpWebRequest hwReq = WebRequest.Create(uri) as HttpWebRequest;

        if ((string.IsNullOrEmpty(UserID) == false) && (string.IsNullOrEmpty(Password) == false))
            hwReq.Credentials = new NetworkCredential(UserID, Password);

        hwReq.Method = WebRequestMethods.Http.Get;
        hwReq.KeepAlive = KeepAlive;
        hwReq.Timeout = Timeout;

		using (HttpWebResponse hwRes = hwReq.GetResponse() as HttpWebResponse)
		{
			using (StreamReader reader = new StreamReader(hwRes.GetResponseStream(), TextEncoding))
			{
				strRet = reader.ReadToEnd();
			}
		}
		return strRet;
	}
 
	public static string HttpPost(string strUrl, Dictionary<string, string> postData)
	{
		return InternetClient.HttpPost(strUrl, postData, System.Text.Encoding.Default);
	}
 
	public static string HttpPost(string strUrl, Dictionary<string, string> postData, Encoding TextEncoding)
	{
		string strRet = "";
		Uri uri = new Uri(strUrl);
		HttpWebRequest hwReq = WebRequest.Create(uri) as HttpWebRequest;

        if ((string.IsNullOrEmpty(UserID) == false) && (string.IsNullOrEmpty(Password) == false))
            hwReq.Credentials = new NetworkCredential(UserID, Password);

        hwReq.Method = WebRequestMethods.Http.Post;
        hwReq.KeepAlive = KeepAlive;
        hwReq.Timeout = Timeout;
		hwReq.ContentType = "application/x-www-form-urlencoded";
 
		StringBuilder data = new StringBuilder();
		string ampersand = "";
		foreach (string key in postData.Keys)
		{
			data.Append(ampersand).Append(key).Append("=").Append(HttpUtility.UrlEncode(postData[key]));
			ampersand = "&";
		}
 
		byte[] byteData = UTF8Encoding.UTF8.GetBytes(data.ToString());
 
		// 設定寫入內容長度
		hwReq.ContentLength = byteData.Length;
 
		// 寫入 POST 參數  
		using (Stream postStream = hwReq.GetRequestStream())
		{
			postStream.Write(byteData, 0, byteData.Length);
		}
 
		using (HttpWebResponse hwRes = hwReq.GetResponse() as HttpWebResponse)
		{
			using (StreamReader reader = new StreamReader(hwRes.GetResponseStream(), TextEncoding))
			{
				strRet = reader.ReadToEnd();
			}
		}
		return strRet;
    }
#endregion Http

#region Ftp
    public static string FtpDownload(string strUrl)
    {
        return InternetClient.FtpDownload(strUrl, System.Text.Encoding.Default);
    }

    public static string FtpDownload(string strUrl, Encoding TextEncoding)
    {
        string strRet = "";
        Uri uri = new Uri(strUrl);
        FtpWebRequest fwReq = WebRequest.Create(uri) as FtpWebRequest;

        if ((string.IsNullOrEmpty(UserID) == false) && (string.IsNullOrEmpty(Password) == false))
            fwReq.Credentials = new NetworkCredential(UserID, Password);

        fwReq.Method = WebRequestMethods.Ftp.DownloadFile;
        fwReq.KeepAlive = KeepAlive;
        fwReq.Timeout = Timeout;

        using (FtpWebResponse fwRes = fwReq.GetResponse() as FtpWebResponse)
        {
            using (StreamReader reader = new StreamReader(fwRes.GetResponseStream(), TextEncoding))
            {
                strRet = reader.ReadToEnd();
            }
        }
        return strRet;
    }
   
#endregion Ftp
}

*檔案 Weather.cs
第1種從FTP抓TXT資料的方法, 大約是2年前寫的
第2種從HTTP抓XML資料的方法, 大約是數個月前在政府的開放資料平台上看到有提供XML版本的天氣資料, 這幾天才寫的

using System;
using System.Text;
using System.Text.RegularExpressions;
using System.Globalization;
using System.Xml;

namespace OpenData
{
    /// <summary>
    /// 使用class InternetClient 取得遠端HTTP或FTP的天氣資料
    /// </summary>
    public class Weather
    {
        /// <summary>
        /// 自中央氣象局的FTP, 抓取TXT版本的資料(BIG5)
        /// </summary>
        /// <param name="strRegion">地區</param>
        /// <param name="strWeather">傳出天氣</param>
        /// <param name="strTemperature">傳出溫度</param>
        /// <returns>資料取得是否成功? true 或 false</returns>
        public static bool getTaiwanData(string strRegion, ref string strWeather, ref string strTemperature)
        {
            try
            {
                DateTime now = DateTime.Now;

                //有效時間:12時起至18時
                string strUrl = "ftp://ftpsv.cwb.gov.tw/pub/forecast/W002.txt";

                if ((now.Hour >= 18) || (now.Hour <= 6))
                {
                    //有效時間:18時起至6時
                    strUrl = "ftp://ftpsv.cwb.gov.tw/pub/forecast/W042.txt";
                }

                string strFileText = InternetClient.FtpDownload(
                    strUrl
                    , Encoding.GetEncoding("BIG5"));

                //([\u2E80-\u9FFF]{7})([\u2E80-\u9FFF]+)([\s\uff10-\uff19]+\uff05)(.+)
                string pat = @"([\u2E80-\u9FFF]{7})([\u2E80-\u9FFF]+)([\s\uff10-\uff19]+\uff05)(.+)";

                // Instantiate the regular expression object.
                Regex r = new Regex(pat, RegexOptions.IgnoreCase);

                // Match the regular expression pattern against a text string.
                Match m = r.Match(strFileText);

                string str1;    //地區
                string str2;    //天氣(晴時多雲,多雲時晴...)
                string str3;    //濕度
                string str4;    //氣溫

                while (m.Success)
                {
                    str1 = m.Groups[1].Value.Trim();

                    if (str1 == strRegion)
                    {
                        str2 = m.Groups[2].Value.Trim();
                        str3 = m.Groups[3].Value.Trim();
                        str4 = m.Groups[4].Value.Trim();

                        strWeather = str2;
                        strTemperature = str4.Replace(" ", "").Replace("-", "~") + "℃";

                        return true;
                    }

                    m = m.NextMatch();
                }

                return false;
            }
            catch 
            {
                return false;
            }
        }

        /// <summary>
        /// 自中央氣象局的HTTP, 抓取XML版本的資料(UTF8)
        /// </summary>
        /// <param name="strRegion">地區</param>
        /// <param name="strWeather">傳出天氣</param>
        /// <param name="strTemperature">傳出溫度</param>
        /// <param name="strImgID">傳出圖示代號</param>
        /// <returns>資料取得是否成功? true 或 false</returns>
        public static bool getTaiwanData(string strRegion, ref string strWeather, ref string strTemperature, ref string strImgID)
        {
            try
            {
                string strXml = InternetClient.HttpGet(
                    "http://www.cwb.gov.tw/opendata/forecast/wf36hrC.xml",
                    Encoding.UTF8);

                XmlDocument xml = new XmlDocument();
                xml.LoadXml(strXml);

                XmlNodeList xnList = xml.SelectNodes("/fifowml/data/location[@type='region']");
                foreach (XmlNode xn in xnList)
                {
                    if (xn.FirstChild.InnerText == strRegion)
                    {
                        XmlNodeList xnListWx = xn.SelectNodes("weather-elements/Wx/time");
                        if (xnListWx.Count != 0)
                        {
                            strWeather = xnListWx[0].FirstChild.InnerText;
                            strImgID = xnListWx[0].LastChild.InnerText;
                        }
                        string strMaxT = "", strMinT = "";
                        XmlNodeList xnListMaxT = xn.SelectNodes("weather-elements/MaxT/time");
                        if (xnListMaxT.Count != 0)
                        {
                            strMaxT = xnListMaxT[0].FirstChild.InnerText;
                        }
                        XmlNodeList xnListMinT = xn.SelectNodes("weather-elements/MinT/time");
                        if (xnListMinT.Count != 0)
                        {
                            strMinT = xnListMinT[0].FirstChild.InnerText;
                        }

                        strTemperature = strMaxT + "~" + strMinT + "℃";

                        return true;
                    }
                }

                return false;
            }
            catch 
            {
                return false;
            }
        }   
    }
}

上一篇
C#應用(1)開始
下一篇
C#應用(3)以WMI寫個SysInfo小工具
系列文
c#應用13

1 則留言

我要留言

立即登入留言