博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
关于中国天气(Weather.com.cn)的查询
阅读量:7240 次
发布时间:2019-06-29

本文共 1984 字,大约阅读时间需要 6 分钟。

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

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

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

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

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

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

    

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

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

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

有了上述基础后,我们就可以简单的写一个小程序获取所有城市的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环境)。

 

转载地址:http://ruybm.baihongyu.com/

你可能感兴趣的文章
AR2831与Squid对接实现web cache功能
查看>>
我的友情链接
查看>>
dom4j解析和生成XML文档
查看>>
键盘的扫描码虚拟码概念 常见Windows键盘按键虚拟码
查看>>
webcast
查看>>
PHP实现跨域自动登录
查看>>
java多线程系列(四)---ReentrantLock的使用
查看>>
PHP问题 —— Warning: PHP Startup: Unable to load dyna
查看>>
XMLHttpRequest Post参数
查看>>
1.2.方法的参数
查看>>
oracle 数据库(表)的逻辑备份与恢复
查看>>
Windows程序设计【001】第一个Windows程序
查看>>
5.1 priority_queue使用
查看>>
如何提高企业云ERP系统生产计划执行率
查看>>
php数据序列化测试
查看>>
errno的陷阱
查看>>
CentOS 7 主机名的修改
查看>>
troubleshooting shuffle reduce端缓冲大小以避免OOM
查看>>
全球1.7万台Mac电脑感染新恶意软件iWorm
查看>>
SpringMVC bean validator 自定义注解
查看>>