关于中国天气(Weather.com.cn)的查询

系统 2171 0

转自:http://www.cnblogs.com/TianFang/archive/2013/01/03/2842913.html

这两天看了下如何获取天气预报,写篇文章总结下:

Weather.com有如下三个Json格式的查询接口,以北京为例:

直接访问它就可以获取到Json格式的数据,解析后就可以用了。其中第三个m.weather.com.cn的信息最全,其它的几个做一个当天的天气预报也够用了。要获取其它城市的天气,只需要把标红的城市ID改成其它ID即可,至于城市的ID如何获取,下面就简单的介绍一下。

ID是一个9位的数字,按照长度可以分为如下四部分:

     101(国家代号)   01(省)   01(二级地区)   00(三级地区)

其中前面三位国家代号101是固定的,无需获取。关键是获取后面三级地区编码代号。要获取所有的地区代码,可以通过如下地址获取:

     http://m.weather.com.cn/data5/city 0101.xml

它有一个参数,就是地区代号,返回的是下一级的地区代号。另外,虽然它的uri格式是一个xml,实际上返回的可不是xml,而是一个类似" 01|北京,02|上海,03|天津,04|重庆 "的格式化的字符串,不过也很好解析就是啦。

要获取所有的地区代号,可以通过如下方式:

  1. 访问 http://m.weather.com.cn/data5/city.xml 得到所有省的编号(示例:01|北京,02|上海,03|天津)
  2. 根据省的编号获取所有二级地区的编号,以北京为例,访问 http://m.weather.com.cn/data5/city 01.xml 即可。
  3. 根据二级编号访问即可获取三级编号,示例: http://m.weather.com.cn/data5/city 0101.xml

有了上述基础后,我们就可以简单的写一个小程序获取所有城市的ID了

     class   CityInfo
    {
         public   string  Name {  get private   set ; }
         public   string  Id {  get private   set ; }

         private  CityInfo()         //
这个对象不能被外部创建
        {
        }

         public   override   string  ToString()
        {
             return   string .Format( "[{0}, {1}]" , Name, Id);
        }

         static   HttpClient  httpClient =  new   HttpClient ();

         async   Task < CityInfo []> GetSubCitiesAsync()
        {
             var  requestUrl =  string .Format( "http://m.weather.com.cn/data5/city{0}.xml" , Id);
             var  result =  await  httpClient.GetStringAsync(requestUrl);

             var  cityInfo =  from  city  in  result.Split( ',' )
                          let  data = city.Split( '|' )
                          select   new   CityInfo () { Id = data[0], Name = data[1] };

             return  cityInfo.ToArray();
        }

         static   async   Task < IEnumerable < CityInfo >> GetSubCitiesAsync( IEnumerable < CityInfo > cities)
        {
             var  tasks = cities.Select(i => i.GetSubCitiesAsync());
             await   Task .WhenAll(tasks);

             return  tasks.Select(i => i.Result).SelectMany(i => i);
        }

         public   static   async   Task < IEnumerable < CityInfo >> GetAllCitiesAsync()
        {
             var  root =  new   CityInfo ();         //
空对象 0
级对象
             var  level1Cities =  await  root.GetSubCitiesAsync();
             var  level2Cities =  await  GetSubCitiesAsync(level1Cities);
             var  level3Cities =  await  GetSubCitiesAsync(level2Cities);

             return  level3Cities;
        }
    }

这个类使用非常简单,它就只有一个接口 GetAllCitiesAsync() ,通过它可以返回所有三级城市的ID。

     foreach  ( var  item  in   await   CityInfo .GetAllCitiesAsync())
    {
         Console .WriteLine(item);
    }

由于获取速度主要依赖于网络,我这里的逻辑做得比较简单,并没有刻意追求最高效率。简单的试了下,大概20s左右能返回结果,总共有2564个城市,这么看来网上的那份城市ID列表是不全的。

关于城市列表,我这里就不贴了,有需要的自己把我上面的代码运行一下即可(需要.net 4.5环境)。

关于中国天气(Weather.com.cn)的查询


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论