本文是借鉴天极网上的一片文章(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上的数据,当然您也可以用其它网页上的数据。
|