轉(zhuǎn)自:http://www.cnblogs.com/TianFang/archive/2013/01/03/2842913.html
這兩天看了下如何獲取天氣預(yù)報(bào),寫篇文章總結(jié)下:
Weather.com有如下三個(gè)Json格式的查詢接口,以北京為例:
直接訪問它就可以獲取到Json格式的數(shù)據(jù),解析后就可以用了。其中第三個(gè)m.weather.com.cn的信息最全,其它的幾個(gè)做一個(gè)當(dāng)天的天氣預(yù)報(bào)也夠用了。要獲取其它城市的天氣,只需要把標(biāo)紅的城市ID改成其它ID即可,至于城市的ID如何獲取,下面就簡(jiǎn)單的介紹一下。
ID是一個(gè)9位的數(shù)字,按照長(zhǎng)度可以分為如下四部分:
???? 101(國(guó)家代號(hào)) ? 01(省) ? 01(二級(jí)地區(qū)) ? 00(三級(jí)地區(qū))
其中前面三位國(guó)家代號(hào)101是固定的,無需獲取。關(guān)鍵是獲取后面三級(jí)地區(qū)編碼代號(hào)。要獲取所有的地區(qū)代碼,可以通過如下地址獲取:
???? http://m.weather.com.cn/data5/city 0101.xml
它有一個(gè)參數(shù),就是地區(qū)代號(hào),返回的是下一級(jí)的地區(qū)代號(hào)。另外,雖然它的uri格式是一個(gè)xml,實(shí)際上返回的可不是xml,而是一個(gè)類似" 01|北京,02|上海,03|天津,04|重慶 "的格式化的字符串,不過也很好解析就是啦。
要獲取所有的地區(qū)代號(hào),可以通過如下方式:
-
訪問 http://m.weather.com.cn/data5/city.xml 得到所有省的編號(hào)(示例:01|北京,02|上海,03|天津)
-
根據(jù)省的編號(hào)獲取所有二級(jí)地區(qū)的編號(hào),以北京為例,訪問 http://m.weather.com.cn/data5/city 01.xml 即可。
-
根據(jù)二級(jí)編號(hào)訪問即可獲取三級(jí)編號(hào),示例: http://m.weather.com.cn/data5/city 0101.xml 。
有了上述基礎(chǔ)后,我們就可以簡(jiǎn)單的寫一個(gè)小程序獲取所有城市的ID了
????
class
?
CityInfo
????{
????????
public
?
string
?Name {?
get
;?
private
?
set
; }
????????
public
?
string
?Id {?
get
;?
private
?
set
; }
????????
private
?CityInfo()????????
//
這個(gè)對(duì)象不能被外部創(chuàng)建
????????{
????????}
????????
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
();????????
//
空對(duì)象
為
0
級(jí)對(duì)象
????????????
var
?level1Cities =?
await
?root.GetSubCitiesAsync();
????????????
var
?level2Cities =?
await
?GetSubCitiesAsync(level1Cities);
????????????
var
?level3Cities =?
await
?GetSubCitiesAsync(level2Cities);
????????????
return
?level3Cities;
????????}
????}
這個(gè)類使用非常簡(jiǎn)單,它就只有一個(gè)接口 GetAllCitiesAsync() ,通過它可以返回所有三級(jí)城市的ID。
????
foreach
?(
var
?item?
in
?
await
?
CityInfo
.GetAllCitiesAsync())
????{
????????
Console
.WriteLine(item);
????}
由于獲取速度主要依賴于網(wǎng)絡(luò),我這里的邏輯做得比較簡(jiǎn)單,并沒有刻意追求最高效率。簡(jiǎn)單的試了下,大概20s左右能返回結(jié)果,總共有2564個(gè)城市,這么看來網(wǎng)上的那份城市ID列表是不全的。
關(guān)于城市列表,我這里就不貼了,有需要的自己把我上面的代碼運(yùn)行一下即可(需要.net 4.5環(huán)境)。
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號(hào)聯(lián)系: 360901061
您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對(duì)您有幫助就好】元
