由於個人研究需要,需要采集天氣歷史數據,前一篇文章:C#+HtmlAgilityPack+XPath帶你采集數據(以采集天氣數據為例子),介紹了基本的采集思路和核心代碼,經過1個星期的采集,歷史數據庫基本全了,現在開放該數據庫,目的是為了讓可能需要該類型做相關研究准備的,至於實時天氣的采集本項目也做了,暫時不公布,如果有需求的,單獨好我聯系,原因很簡單,人家小站也不容易,大家一起拖,容易搞死,主要大家都不能用。
.NET開源項目:【目錄】本博客其他.NET開源項目文章目錄
本文原文地址:分享2011-2015年全國城市歷史天氣數據庫【Sqlite+C#訪問程序】
1.天氣數據庫介紹
該數據的基本情況如下:
-
該數據庫目前覆蓋了全國34個省、直轄市、自治區以及特別行政區的所有縣級市區。
-
該數據庫的歷史天氣時間范圍是2011年1月至2015年8月底的數據,實時天氣預報的更新接口暫時不開放,但我們會對核心采集進行簡單的介紹,請看第3節內容。
-
包括的天氣數據有:天氣情況,氣溫情況,風力情況。
-
目前總的天氣記錄條數為390萬,,大小為570M,壓縮后的版本大小為60M,后續還會增加,考慮每2-3個月更新一次。目前為一個總庫
-
考慮到實際的城市等級,我對省份和城市進行了大概分級,具體研究分析的時候可以自己單獨提取城市,單獨處理。
1.省、直轄市、自治區,特別行政區,等級:1
2.地級市,或者同等州 ,等級:2
3.縣市區,等級:3
4.省會中心城市:5
本文使用C#+XCode進行開發,大部分查詢方法都在實體類中寫好了。下面我們將會簡單介紹一些。
2.數據庫設計
該數據庫設計比較簡單,第一個表是基礎城市信息表,存儲城市的名稱,等級,代碼,所屬省份以及地區等基本信息;第二個表是原始天氣數據表,存儲采集過來的原始天氣信息,主要信息是名稱,天氣狀況,考慮到數據小,對一些字段進行了冗余,避免重復查找。第三個表是處理后的天氣數據表,如何處理看個人情況進行,我自己還沒想好,只是先采集了原始數據。數據庫的結構如下圖:
上述3個表的基本結構看上面,比較簡單,有的表字段進行了冗余,沒必要為了所謂的范式把自己搞死。看看下面Gif動態演示圖:
3.關於采集預報信息
我們在前面一篇文章中介紹了基本的頁面采集方法。頁面分析過程就不介紹了,有空的朋友看前一篇文章: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 < N; i++) { //日期 - 天氣狀況 - 氣溫 - 風力風向 //白天 var td = dd[2 * i + 1].SelectNodes(@"td"); var date = td[0].InnerText.Replace(" ", "").Trim(); var btq = td[2].InnerText.Replace(" ", "").Trim(); var bqw = td[3].InnerText.Replace(" ", "").Trim(); var bfx = td[4].InnerText.Replace(" ", "").Trim(); //晚上 var tdw = dd[2 * i + 2].SelectNodes(@"td"); var wtq = tdw[1].InnerText.Replace(" ", "").Trim(); var wqw = tdw[2].InnerText.Replace(" ", "").Trim(); var wfx = tdw[3].InnerText.Replace(" ", "").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);
看看結果:
5.數據庫和程序下載
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版本來說,太大了,而且以后還會持續增加,如果有資源的朋友,可以幫忙掛一下。