取得中央氣象局的各地天氣資料
相關技術:
*WebRequest與HttpWebRequest與HttpWebResponse
*FtpWebRequest與FtpWebResponse
*Regex與Match
*XmlDocument與XmlNodeList
回目錄
*檔案 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;
}
}
}
}