zoukankan      html  css  js  c++  java
  • [原创] 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/
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。
  • 相关阅读:
    Web服务器安全设置
    java大文件读写操作,java nio 之MappedByteBuffer,高效文件/内存映射
    Java IO和Java NIO在文件拷贝上的性能差异分析
    Java高效读取大文件
    NIO入门之轻松读取大文件
    我来说说java的NIO
    java读取大文件 超大文件的几种方法
    @RequestBody 的正确使用办法
    友鱼项目知识点
    怎样查看Tomcat动态控制台信息
  • 原文地址:https://www.cnblogs.com/brucezhang80/p/csharp_get_weather_forecast_by_baidu_weather_api.html
Copyright © 2011-2022 走看看