用C#打造一个天气预报的WebService

[ 2006-04-09 01:24:18 | 作者: admin ]
字号: | |
本文是我借鉴天极网上的一片文章(SmartPhone手机上查看QQ天气预报)而改写的,本文的大部分代码是原文的,是在原文的基出上做了改进(主要是针对GetWeatherDataSet(string cityName)做的修改),在原文中,所取出的数据都是包含HTML标记的,这样的数据放到网页上会破坏原有的排版,所以我在文件加入我我自已写的函数解决了此问题;还有就是原文中就是每次访问Service都要到天气预报网页上取一次数据,这样造成了很大的资源浪费,所以我在本地用Application做的缓存,只有当网页上数据日期过期时才会到网页上去收集新的信息。

        本文所用到的组件(Binken.Platform.General_Function)可以到 一个常用的 Asp.Net常用函数库 下载。

1、建立一个名为WeatherService的WebService,并将QQ的天气服务转为XML WebService服务,部署在一台具有固定IP的服务器上。

2、新建一个WeatherDataSet.XSD,存储我们的天气信息

<?xml version="1.0" encoding="utf-8" ?>
<xs:schema id="WeatherDataSet"
                    targetNamespace="Sailong.Services.WeatherService"
                    elementFormDefault="qualified"
                    attributeFormDefault="qualified"
                    xmlns="Sailong.Services.WeatherService"
                    xmlns:mstns="Sailong.Services.WeatherService"
                    xmlns:xs="http://www.w3.org/2001/XMLSchema"
                    xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
  <xs:element name="WeatherDataSet" msdata:IsDataSet="true">
    <xs:complexType>
            <xs:choice maxOccurs="unbounded">
            <xs:element name="WeatherDS">
            <xs:complexType>
      <xs:sequence>
              <xs:element name="CityName" type="xs:string" minOccurs="0" ></xs:element>
              <xs:element name="Date1" type="xs:string" minOccurs="0" ></xs:element>
              <xs:element name="Weather1" type="xs:string" minOccurs="0" ></xs:element>
              <xs:element name="Temp1" type="xs:string" minOccurs="0" ></xs:element>
              <xs:element name="WindPower1" type="xs:string" minOccurs="0" ></xs:element>
              <xs:element name="Date2" type="xs:string" minOccurs="0" ></xs:element>
              <xs:element name="Weather2" type="xs:string" minOccurs="0" ></xs:element>
              <xs:element name="Temp2" type="xs:string" minOccurs="0" ></xs:element>
              <xs:element name="WindPower2" type="xs:string" minOccurs="0" ></xs:element>
        </xs:sequence>
        </xs:complexType>
        </xs:element>
        </xs:choice>
      </xs:complexType>
      </xs:element>
</xs:schema>


3、WeatherService的源代码如下

using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Web;
using System.Web.Services;
using System.IO;
using System.Net;
using System.Text;
using Binken.Platform.General_Function;


namespace WeatherService
{
        [WebService(Description="WeatherService 天气Service",Namespace="WeatherService")]
        /// <summary>
        /// 天气预报Service
        /// </summary>
        public class Weather : System.Web.Services.WebService
        {
               #region Variable
               private string tommorow;
               #endregion

               #region 构造函数
               public Weather ()
               {
                    //CODEGEN: 该调用是 ASP.NET Web 服务设计器所必需的
                    InitializeComponent();
               }
               #endregion

               #region 组件设计器生成的代码
               
               //Web 服务设计器所必需的
               private IContainer components = null;
                   
               /// <summary>
               /// 设计器支持所需的方法 - 不要使用代码编辑器修改
               /// 此方法的内容。
               /// </summary>
               private void InitializeComponent()
               {
               }

               /// <summary>
               /// 清理所有正在使用的资源。
               /// </summary>
               protected override void Dispose( bool disposing )
               {
                    if(disposing && components != null)
                    {
                    components.Dispose();
                    }
                    base.Dispose(disposing);
               }
               
               #endregion

               #region GetWeatherDataSet 天气预报

               [WebMethod(Description="天气预报(DataSet)")]
               public DataSet GetWeatherDataSet(string cityName)
               {
                    string url=@"http://appnews.qq.com/cgi-bin/news_qq_search";
                    string weatherData="";
//DataSet ds = new DataSet ();
try
                    {
                    WeatherDataSet weatherDs = new WeatherDataSet();

                    if(Application ["Weather"] != null)
                    {
                    weatherDs = (WeatherDataSet)Application ["Weather"];
                    string w = weatherDs.Tables[0].Rows [0]["Date1"].ToString();
                   
                    if(DateTime.Parse (w).Date != DateTime.Today.Date )
                    {
                    weatherDs.Clear ();
                    weatherData = GetPage(url,cityName).Replace(" ","").Trim();
                    weatherDs.WeatherDS.AddWeatherDSRow(GetWeatherRow(ref weatherDs, weatherData, cityName) );
                    Application ["Weather"] = weatherDs;
                    }
                    }
                    else
                    {
                    weatherDs.Clear ();
                    weatherData = GetPage(url,cityName).Replace(" ","").Trim();
                    weatherDs.WeatherDS.AddWeatherDSRow(GetWeatherRow(ref weatherDs, weatherData, cityName) );
                    Application ["Weather"] = weatherDs;
                    }
                    return weatherDs;

                    }
                    catch(Exception err)
                    {
                    throw new Exception("对不起,没有这个城市的天气信息!"+ err.ToString ());
                    }
                   
               }
               
               private WeatherDataSet.WeatherDSRow GetWeatherRow(ref WeatherDataSet weatherDs, string weatherData, string cityName)
               {
                    try
                    {
                    Common_Function cf = new Common_Function ();
                    WeatherDataSet.WeatherDSRow weatherRow = weatherDs.WeatherDS.NewWeatherDSRow();
                    weatherRow.CityName = cityName ;
                    weatherRow.Date1 = cf.Text_Remove_WebTag (weatherData.Substring(weatherData.IndexOf(cityName)+ cityName.Length, weatherData.IndexOf("天气")-(weatherData.IndexOf(cityName) + cityName.Length))).Replace (" " , "");
                    //计算明日日期
                    if(DateTime.Parse (weatherRow.Date1).AddDays(1).Month.ToString().Length == 1)
                    {
tommorow= "0" + DateTime.Parse (weatherRow.Date1).AddDays(1).Month.ToString()+"月" + DateTime.Parse (weatherRow.Date1).AddDays(1).Day.ToString()+"日";
                    }
                    else
                    {
                    tommorow= DateTime.Parse (weatherRow.Date1).AddDays(1).Month.ToString()+"月" + DateTime.Parse (weatherRow.Date1).AddDays(1).Day.ToString()+"日";
                    }

                    weatherRow.Weather1 = cf.Text_Remove_WebTag (weatherData.Substring(weatherData.IndexOf("天气")+"天气".Length, weatherData.IndexOf("气温")-(weatherData.IndexOf("天气")+"天气".Length)));
                    weatherRow.Temp1 = cf.Text_Remove_WebTag (weatherData.Substring(weatherData.IndexOf("气温")+"气温".Length,weatherData.IndexOf("风力")-(weatherData.IndexOf("气温")+"气温".Length)).Replace("℃-","℃/"));
                    weatherRow.WindPower1 = cf.Text_Remove_WebTag (weatherData.Substring(weatherData.IndexOf("风力")+"风力".Length,weatherData.IndexOf(tommorow)-(weatherData.IndexOf("风力")+"风力".Length)));
                    weatherRow.Date2 = tommorow;
                    weatherRow.Weather2 = cf.Text_Remove_WebTag (weatherData.Substring(weatherData.LastIndexOf("天气")+"天气".Length,weatherData.LastIndexOf("气温")-(weatherData.LastIndexOf("天气")+"天气".Length)));
                    weatherRow.Temp2 = cf.Text_Remove_WebTag (weatherData.Substring(weatherData.LastIndexOf("气温")+"气温".Length,weatherData.LastIndexOf("风力")-(weatherData.LastIndexOf("气温")+"气温".Length)).Replace("℃-","℃/"));
                    weatherRow.WindPower2 = cf.Text_Remove_WebTag (weatherData.Substring(weatherData.LastIndexOf("风力")+"风力".Length));
                    return weatherRow;
                    }
                    catch(Exception err)
                    {
                    throw new Exception (err.ToString ());
                    }
               }
               
               #endregion
               
               #region GetPageString 获取QQ的天气服务
               
               //private string xx="";
               
               [WebMethod(Description="天气预报(WebPage)")]
               public string GetPageString(string cityName)
               {
                    string url=@"http://appnews.qq.com/cgi-bin/news_qq_search";
                    return GetPage(url,cityName);
               }
               
               /// <summary>
               /// 从QQ上获取天气详细信息
               /// </summary>
               /// <param name="url">QQ气像链接</param>
               /// <param name="cityName">城市名称</param>
               /// <returns>string</returns>
               private static string GetPage(string url,string cityName)
               {
                    HttpWebResponse res = null;
                    string strResult = "";
                    try
                    {
                    string postData = "city=" + HttpUtility.UrlEncode(cityName,System.Text.Encoding.GetEncoding("GB2312"));
                    HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
                    req.Method = "POST";
                    req.KeepAlive = true;
                    req.ContentType = "application/x-www-form-urlencoded";
                    StringBuilder UrlEncoded = new StringBuilder();
                    byte[] SomeBytes = Encoding.ASCII.GetBytes(postData);
                    req.ContentLength = SomeBytes.Length;
                    Stream newStream = req.GetRequestStream();
                    newStream.Write(SomeBytes, 0, SomeBytes.Length);
                    newStream.Close();
                   
                    //获得流内容
                    res = (HttpWebResponse)req.GetResponse();
                    System.IO.Stream s = res.GetResponseStream();
                    StreamReader reader = new StreamReader(s,System.Text.Encoding.Default);
                    strResult = reader.ReadToEnd();
                    }
catch(Exception e)
{
                    strResult = e.ToString();
                    }
                    finally
                    {
                    if ( res != null )
                    {
                    res.Close();
                    }
                    }
                   
                    strResult=strResult.Remove(0,strResult.IndexOf("●"));
                    if( cityName != "北京" )
                    {
                    strResult=strResult.Remove(strResult.IndexOf("北京"),strResult.Length-strResult.IndexOf("北京"));
                    }
                    else
                    {
                    strResult=strResult.Remove(strResult.LastIndexOf("北京"),strResult.Length-strResult.LastIndexOf("北京"));
                    }
                   
                    strResult=strResult.Trim();
                    while(strResult.IndexOf(@"<") != -1)
                    {
                    strResult=strResult.Remove(strResult.IndexOf(@"<"),strResult.IndexOf(@">")-strResult.IndexOf(@"<")+1);
                    }
                    while(strResult.IndexOf(@" ") != -1)
                    {
                    strResult=strResult.Replace(" ","");
                    }
                    string x = Encoding.UTF8.GetString(new Byte[]{10});
                    string y = Encoding.UTF8.GetString(new Byte[]{9});
                    while(strResult.IndexOf(x) != -1)
                    {
                    strResult=strResult.Replace(x,"");
                    }
                    while(strResult.IndexOf(y) != -1)
                    {
                    strResult=strResult.Replace(y,"");
                    }
                    return strResult;
               }
               
               #endregion
        }
}

4、记得将在Web.Config文件加入以下节点,使得WebService能被外部访问

<!-- WebService 获取的途径 -->
<webServices>
<protocols>
<add name="HttpSoap"/>
<add name="HttpPost"/>
<add name="HttpGet"/>
<add name="HttpPostLocalhost"/?
<add name="Documentation"/>
</protocols>
</webServices>

OK,编译后架到服务器上,就可以用客户端实时获取气象数据了,也可以在SmartPhone手机上查看天气预报,本文所取的数据是QQ上的数据,当然您也可以用其它网页上的数据。

评论Feed 评论Feed: http://blog.xg98.com/feed.asp?q=comment&id=409

这篇日志没有评论。

此日志不可发表评论。