[置顶]【开源】分享2011-2015年全国城市历史天气数据库【Sqlite+C#访问程序】
该数据库的历史天气时间范围是2011年1月至2015年8月底的数据,实时天气预报的更新接口暂时不开放,但我们会对核心采集进行简单的介绍,请看第3节内容。
目前总的天气记录条数为390万,,大小为570M,压缩后的版本大小为60M,后续还会增加,考虑每2-3个月更新一次。目前为一个总库
考虑到实际的城市等级,我对省份和城市进行了大概分级,具体研究分析的时候可以自己单独提取城市,单独处理。
1.省、直辖市、自治区,特别行政区,等级:1
2.地级市,或者同等州 ,等级:2
3.县市区,等级:3
4.省会中心城市:5
本文使用C#+XCode进行开发,大部分查询方法都在实体类中写好了。下面我们将会简单介绍一些。
2.数据库设计 该数据库设计比较简单,第一个表是基础城市信息表,存储城市的名称,等级,代码,所属省份以及地区等基本信息;第二个表是原始天气数据表,存储采集过来的原始天气信息,主要信息是名称,天气状况,考虑到数据小,对一些字段进行了冗余,避免重复查找。第三个表是处理后的天气数据表,如何处理看个人情况进行,我自己还没想好,只是先采集了原始数据。数据库的结构如下图:
上述3个表的基本结构看上面,比较简单,有的表字段进行了冗余,没必要为了所谓的范式把自己搞死。看看下面Gif动态演示图:
我们在前面一篇文章中介绍了基本的页面采集方法。页面分析过程就不介绍了,有空的朋友看前一篇文章:C#+HtmlAgilityPack+XPath带你采集数据(以采集天气数据为例子),这里直接贴出核心代码:
//直接采集月份,每个城市从2011 01 开始的数据至今都有 String url = String.Format("http://www.tianqihoubao.com/yubao/{0}.html", cityName); //先要拼接链接,根据名称 var docText = HtmlHelper.GetWebClient(url); var doc = new HtmlDocument(); doc.LoadHtml(docText); var res = doc.DocumentNode.SelectSingleNode(@"/html[1]/body[1]/div[2]/div[6]/div[1]/div[1]/table[1]"); if (res != null) var dd = res.SelectNodes(@"tr"); if (dd.Count 3) return;//3或者4个以上子节点tr if ((dd.Count - 1) % 2 == 0) //tr成对出现 Int32 N = (dd.Count - 1) / 2; for (int i = 0; i i++) //日期 - 天气状况 - 气温 - 风力风向 //白天 var td = dd[2 * i + 1].SelectNodes(@"td"); var date = td[0].InnerText.Replace(" nbsp;", "").Trim(); var btq = td[2].InnerText.Replace(" nbsp;", "").Trim(); var bqw = td[3].InnerText.Replace(" nbsp;", "").Trim(); var bfx = td[4].InnerText.Replace(" nbsp;", "").Trim(); //晚上 var tdw = dd[2 * i + 2].SelectNodes(@"td"); var wtq = tdw[1].InnerText.Replace(" nbsp;", "").Trim(); var wqw = tdw[2].InnerText.Replace(" nbsp;", "").Trim(); var wfx = tdw[3].InnerText.Replace(" nbsp;", "").Trim(); Console.WriteLine("{0}/{1},{2}/{3},{4}/{5},{6}", wtq, btq, wqw, bqw, wfx, bfx,date); }4.基本使用方法
下面给出数据库的几个常规查询方法,如果懂XCode的朋友,更加容易理解,熟悉表结构就行了。
4.1 查询某个省份所有地级市列表由于地级市的等级为2或者5,所以要注意一些,而且县级市的省份属性里面也包括了Province,因此不能单独判定。
/// summary 查询某个省份,所有地级市列表 /summary /// param name="provinceName" 省份名称 /param /// returns /returns public static EntityList BaseCityInfo FindAllCityByProvince(String provinceName) return BaseCityInfo.FindAll( BaseCityInfo._.Province == provinceName BaseCityInfo._.Level 1 //不能为省份 BaseCityInfo._.Level !=3);//要包括省会中心城市,也就是Level=2或者5 }4.2 查询地级市下所有县市列表
县级市都是等级为3,所以查询地区名称以及等级就可以了。
/// summary 查询某个地级市下面的所有县级市列表 /summary /// param name="areaName" 市区名称 /param /// returns /returns public static EntityList BaseCityInfo FindAllCityByArea(String areaName) return BaseCityInfo.FindAll(BaseCityInfo._.Area == areaName BaseCityInfo._.Level ==3);//Level=3是县级市区 }4.3 查询某个地区某个月的天气情况
查询某个地区,和时间范围的天气情况,直接加条件即可,地区按照名称来XCode的查询语法举一反三,应该比较好理解。
/// summary 查询某个地区某个月的天气情况 /summary /// param name="cityName" 城市名称 /param /// returns /returns public static EntityList OriginWeatherData FindCityWeatherByMonth(String cityName) return OriginWeatherData.FindAll( OriginWeatherData._.Name == cityName OriginWeatherData._.DateTime = new DateTime(2015, 8, 31) OriginWeatherData._.DateTime =new DateTime (2015,8,1), OriginWeatherData._.DateTime.Asc(),null,0,0); }4.4 数据库Sql查询演示与XCode版代码
为了更加直观,我们对数据库进行了简单的查询演示,390万代码实际速度并不慢,看看效果。里面的Sql语句,下面都将使用XCode代码进行重写演示,大家可以借鉴用法:
我们看看XCode的查询方法:
//获取所有的地级市+县级市区的数量 var cityCount = BaseCityInfo.FindCount(BaseCityInfo._.Level 1, null, null, 0, 0); //获取所有记录总数,截至时间2015-08-29和2015-09-03 var totalCount = OriginWeatherData.FindCount(); //获取从2015-08-21开始的上海地区的天气情况 var shanghaiRecords = OriginWeatherData.FindAll (OriginWeatherData._.Name == "上海" OriginWeatherData._.DateTime new DateTime(2015, 08, 20), OriginWeatherData._.Id.Asc(), null, 0, 0); //获取上海地区总的天气数目,注意只是上海地区总的,不包括下属县市区 var shCount = OriginWeatherData.FindCount(OriginWeatherData._.Name, "上海"); //获取浙江省地级市区所有的天气记录 var zjRecords = OriginWeatherData.FindAll (OriginWeatherData._.Province == "浙江" (OriginWeatherData._.Level == 2 | OriginWeatherData._.Level == 5), null,null,0,0); //获取2015年8月20日浙江省地级市区所有的天气记录 var zj = OriginWeatherData.FindAll (OriginWeatherData._.Province == "浙江" OriginWeatherData._.DateTime new DateTime(2015, 08, 20) (OriginWeatherData._.Level == 2 | OriginWeatherData._.Level == 5), null, null, 0, 0);
看看结果:
Sqlite版数据库下载:http://pan.baidu.com/s/1pJ02EmR 密码:jzmt ,
如果链接错误,请到原地址下载:分享2011-2015年全国城市历史天气数据库【Sqlite+C#访问程序】
C#版访问程序,注意是Sqlite是32位的版本:天气数据库访问程序.rar
使用方法:把数据库放在bin目录,或者自己修改配置文件的地址。
数据大部分截至2015年8月30日-2015年9月2日,按照地区会有不一样,以后会逐步同步起来。
核心代码不直接开放,但完全免费对有需要的人开放。需要的人可以QQ联系,或者邮件联系我,请注明自己的一些基本个人信息和用途。
由于时间紧,考虑不够全面,我将在下一个版本中对数据库进行分库,提高数据查询效率。目前的数据库对于sqlite版本来说,太大了,而且以后还会持续增加,如果有资源的朋友,可以帮忙挂一下。
相关文章
- C#操作配置文件中appSettings,connectionStrings节点「建议收藏」
- 《CLR via C#》笔记:第4部分 核心机制(4)
- C# Timer控件学习之使用Timer解决按钮幂等性问题案例分享
- c# 多线程并发-金三银四面试:C#.NET面试题高级篇2-多线程
- c#面试题抽象类和接口的区别-金三银四面试:C#程序员经常遇到的30道基础面试题,想你所想
- C# HttpClient使用和注意事项,.NET Framework连接池并发限制
- C# json 传参发送 post 请求例子
- 迁移升级:从SQLite到MySQL(sqlite转mysql)
- MySQL到SQLite转换:一步到位(mysql转sqlite)
- 的区别SQLite和MySQL: 突出的不同特点(sqlite和mysql)
- SQL Server连接SQLite实现数据互通(mssql连sqlite)
- C与MySQL结合一个简单的示例(c# mysql 例子)
- C操作Oracle数据库实现图片存取(c# oracle 图片)
- 使用SQLite和Redis提升系统性能(sqlite redis)
- VisualC#.Net网络程序开发-Socket篇
- 设置C#窗体程序只能启动一次
- c#多线程编程入门篇
- 保护你的Sqlite数据库(SQLite数据库安全秘籍)
- 使用C#调用系统API实现内存注入的代码
- C#读写操作app.config中的数据应用介绍
- 解析C#中委托的同步调用与异步调用(实例详解)
- C#正则表达式分解和转换IP地址实例(C#正则表达式大全c#正则表达式语法)
- C#中的位操作小结
- c#执行excel宏模版的方法
- C#函数式编程中的惰性求值详解