[原创] C#(asp.net)调用百度天气预报API自定义天气预报显示效果

  介绍  

     最近在做一个企业项目,需要根据用户的地理位置显示该地区的天气预报,且界面要定制开发,不能使用其它网站的插件,找了一遍天气预报API,中国天气网(http://www.weather.com.cn/)的最坑爹,原本获取一周天气的API很好用,现在要申请,由于项目比较急所以没有花时间去申请,后来又试了新浪的天气预报接口,也可以用,就是地区名称要转一下码,返回json数据格式也稍显混乱,所以没有采用。

      最后发现百度天气的API还不错,而且百度首页的天气预报做出来的效果看上去也不错的,所以决定采用百度的天气预报接口,下面就跟我一起实现自定义天气预报的效果。

 

  正文  

  一、获取百度的AK(访问密钥)

      申请地址:http://lbsyun.baidu.com/apiconsole/key

      申请时注意事项:1、选择服务端ak 2、禁用服务不要勾选其中的任何项 3、如果不希望限制该ak发起请求的IP来源,可以设置为  0.0.0.0/0  

      AK为24位的字符串:1and0u3TOj8UpP4sLjChVIwz (访问量总报警,所以请申请自己的AK,3Q)

  二、获取返回数据JSON,生成对应实体类反序列化天气预报数据

      访问:http://api.map.baidu.com/telematics/v3/weather?location=%E5%8C%97%E4%BA%AC&output=json&ak=1and0u3TOj8UpP4sLjChVIwz

      获取到JSON数据格式如下

{
"error": 0,
"status": "success",
"date": "2014-09-03",
"results": [
{
"currentCity": "北京",
"pm25": "66",
"index": [
{
"title": "穿衣",
"zs": "炎热",
"tipt": "穿衣指数",
"des": "天气炎热,建议着短衫、短裙、短裤、薄型T恤衫等清凉夏季服装。"
},
{
"title": "洗车",
"zs": "较适宜",
"tipt": "洗车指数",
"des": "较适宜洗车,未来一天无雨,风力较小,擦洗一新的汽车至少能保持一天。"
},
{
"title": "旅游",
"zs": "适宜",
"tipt": "旅游指数",
"des": "天气较好,但稍感觉有些热,不过还是个好天气哦。适宜旅游,可不要错过机会呦!"
},
{
"title": "感冒",
"zs": "少发",
"tipt": "感冒指数",
"des": "各项气象条件适宜,发生感冒机率较低。但请避免长期处于空调房间中,以防感冒。"
},
{
"title": "运动",
"zs": "较适宜",
"tipt": "运动指数",
"des": "天气较好,户外运动请注意防晒,推荐您在室内进行低强度运动。"
},
{
"title": "紫外线强度",
"zs": "很强",
"tipt": "紫外线强度指数",
"des": "紫外线辐射极强,建议涂擦SPF20以上、PA++的防晒护肤品,尽量避免暴露于日光下。"
}
],
"weather_data": [
{
"date": "周三 09月03日 (实时:21℃)",
"dayPictureUrl": "http://api.map.baidu.com/images/weather/day/qing.png",
"nightPictureUrl": "http://api.map.baidu.com/images/weather/night/qing.png",
"weather": "晴",
"wind": "微风",
"temperature": "18℃"
},
{
"date": "周四",
"dayPictureUrl": "http://api.map.baidu.com/images/weather/day/qing.png",
"nightPictureUrl": "http://api.map.baidu.com/images/weather/night/qing.png",
"weather": "晴",
"wind": "微风",
"temperature": "32 ~ 18℃"
},
{
"date": "周五",
"dayPictureUrl": "http://api.map.baidu.com/images/weather/day/duoyun.png",
"nightPictureUrl": "http://api.map.baidu.com/images/weather/night/duoyun.png",
"weather": "多云",
"wind": "微风",
"temperature": "30 ~ 18℃"
},
{
"date": "周六",
"dayPictureUrl": "http://api.map.baidu.com/images/weather/day/yin.png",
"nightPictureUrl": "http://api.map.baidu.com/images/weather/night/yin.png",
"weather": "阴",
"wind": "微风",
"temperature": "29 ~ 19℃"
}
]
}
]
}
查看代码 返回JSON数据格式

    通过分析,可以将JSON数据定义为对应的类。

    [Serializable]
    public class BaiduWeatherModel
    {
        public int error;
        public string status;
        public string date;
        public Result[] results;
    }
    [Serializable]
    public class Result
    {
        public string currentCity;
        public string pm25;
        public Index[] index;
        public WeatherData[] weather_data;
    }

    [Serializable]
    public class Index
    {
        public string title;
        public string zs;
        public string tipt;
        public string des;
    }

    [Serializable]
    public class WeatherData
    {
        public string date;
        public string dayPictureUrl;
        public string nightPictureUrl;
        public string weather;
        public string wind;
        public string temperature;
    }
查看代码 JSON对应类

    然后将返回的JSON串反序列化为,实体对象

BaiduWeatherModel baiduWeatherModel = JsonConvert.DeserializeObject<BaiduWeatherModel>(json);
查看代码 JSON反序列化

  三、根据用户IP地址获取访问省、市、地区名称

   首先要获取访问页面用户的IP 地址,返回JSON格式字符串:

        private string GetClientIP()
        {
            string result = HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
            if (string.IsNullOrEmpty(result))
            {
                result = HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
            }
            if (string.IsNullOrEmpty(result))
            {
                result = HttpContext.Current.Request.UserHostAddress;
            }
            return result;
        }
查看代码 获取访问用户IP地址
    [Serializable]
    public class ClientIP
    {
        public int ret { get; set; }
        public string start { get; set; }
        public string end { get; set; }
        public string country { get; set; }
        public string province { get; set; }
        public string city { get; set; }
        public string district { get; set; }
        public string isp { get; set; }
        public string type { get; set; }
        public string desc { get; set; }
    }
查看代码 IP返回JSON对应类

   然后根据用户访问地址获取用户所在城市:

        private string GetCurrentUserCityName()
        {
            string strCityName;
            string userIP = GetClientIP();
            string strJson = string.Empty;
            try
            {
                string httpFindIpCityName = "http://int.dpool.sina.com.cn/iplookup/iplookup.php?format=json&ip="+userIP;
                var request = (HttpWebRequest)WebRequest.Create(httpFindIpCityName);
                var response = (HttpWebResponse)request.GetResponse();
                Stream stream = response.GetResponseStream();
                if (stream != null) strJson = new StreamReader(stream, System.Text.Encoding.UTF8).ReadToEnd();
                strCityName = JsonConvert.DeserializeObject<ClientIP>(strJson).city;
                response.Close();
            }
            catch (Exception ex)
            {
                return "北京";
            }

            return string.IsNullOrEmpty(strCityName) ? "北京" : strCityName;
        }
查看代码 根据IP地址获取用户所在城市

  四、根据返回值美化前台显示效果

     经过上面的努力,现在拿到了用户IP,根据IP地址获取到了城市名,下面就根据用户的城市名得到当前访问用户所在地区的天气预报,显示效果最好在前台先建好HTML,画好要显示的格式,最后由后台返回给前台。

        private string GetWeather(string cityName)
        {
            string result = string.Empty;
            try
            {
                var listAk = new List<string>() { "1and0u3TOj8UpP4sLjChVIwz"};
                if (string.IsNullOrEmpty(cityName)) return result;
                foreach (var ak in listAk)
                {
                    string str =
    "http://api.map.baidu.com/telematics/v3/weather?location=" + cityName + "&output=json&ak=" + ak;
                    var request = (HttpWebRequest)WebRequest.Create(str);
                    var response = (HttpWebResponse)request.GetResponse();
                    Stream stream = response.GetResponseStream();
                    if (stream != null)
                    {
                        result = new StreamReader(stream, System.Text.Encoding.UTF8).ReadToEnd();
                        if (result.IndexOf("Error", System.StringComparison.Ordinal) < 0)
                        {
                            response.Close();
                            break;
                        }
                    }
                }
            }
            catch (Exception)
            {
                return result;
            }

            return result;
        }
    }
查看代码 调用百度API获取天气预报
        protected void Page_Load(object sender, EventArgs e)
        {
            string strCityName = GetCurrentUserCityName();
            string json = GetWeather(strCityName);
            var sb = new StringBuilder();
            if (!string.IsNullOrEmpty(json))
            {
                var myModel = JsonConvert.DeserializeObject<MyModel>(json);
                if (myModel != null && myModel.results.Length > 0)
                {
                    sb.AppendLine("<table  border=\"0\" cellspacing=\"0\" cellpadding=\"0\"><tr>");
                    int weatherdayLength = myModel.results[0].weather_data.Length;
                    for (int i = 0; i < weatherdayLength; i++)
                    {
                        var weather = myModel.results[0].weather_data[i];
                        string title = weather.weather + " " + weather.wind;
                        sb.AppendLine("<td>");
                        sb.AppendLine("<table>");
                        sb.AppendLine("<tr><td>" + weather.date + "</td></tr>");
                        sb.AppendLine("<tr><td><img src=\"" + weather.dayPictureUrl + "\"  title=\"" + title + "\"></td></tr>");
                        sb.AppendLine("<tr><td>" + weather.temperature.Replace(" ~ ", "~").Replace("", "") + "</td></tr>");
                        sb.AppendLine("</table>");
                        sb.AppendLine("</td>");
                    }
                    sb.AppendLine("</tr></table>");
                }
            }
            Page.Response.Write(sb.ToString());
        }
查看代码 将天气预报显示到前台 

 总结

      百度在天气预报也做了v1、v2、v3几个版本,每个版本都在不断的完善,现在开放的每日访问量还是有限的,所以需要你多申请几个AK,如果访问页面的人数太多,该AK的访问量用完了,可以换下一个AK继续访问,保证客户访问时不时空白一片。天气预报是个小功能,但也是很多企业内部站点的一个小亮点。

      最终效果图:

作者:布鲁斯张
出处:http://www.cnblogs.com/brucezhang80/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。
原文地址:https://www.cnblogs.com/brucezhang80/p/csharp_get_weather_forecast_by_baidu_weather_api.html