实战系列之天气预报实时采集
前言:
今天 CYQ.Data框架框架群里,“路過冬天”問了個(gè)天氣預(yù)報(bào)的問題,問哪里有webservice調(diào)用?于是隨性就有了這篇文章了。
天氣預(yù)報(bào),回憶中做過那么三次。
第一次的做法是:
技術(shù)總監(jiān)寫了個(gè)采集后臺(tái),每天早晚各采一次,從tq121站里采集大量的天氣信息到數(shù)據(jù)庫,我就直接從數(shù)據(jù)庫里讀數(shù)據(jù)了。
總結(jié):
這種做法很麻煩,每天要開后臺(tái)采數(shù)據(jù),做成自動(dòng)的,還要不半路程序自動(dòng)死亡才行,而且數(shù)據(jù)庫會(huì)產(chǎn)生大堆垃圾過時(shí)的數(shù)據(jù)。
優(yōu)點(diǎn)是:可以采集很多信息,做成很專業(yè)的天氣預(yù)報(bào)站,那時(shí)候做旅游站,天氣也是重要模塊,所以這種方式也很合適。
第二次:
自己做畢業(yè)設(shè)計(jì),都沒采集后臺(tái),自己又寫不出采集來,沒數(shù)據(jù)讀了,只好到處百度搜索“天氣預(yù)報(bào)Webservice"調(diào)用。
總結(jié):
這種做法也很郁悶,首先Webservice不好找,第二找到的如果小站提供的,隨時(shí)又會(huì)掛掉了,要是人家掛掉,你要另找一個(gè)?
優(yōu)點(diǎn)是:找到就調(diào)用,什么也不用管,菜鳥也能飛。
第三次:
是電子商務(wù)平臺(tái)在首頁顯示下天氣,那時(shí)候正巧遇到剛做完web版的采集系統(tǒng),于是順理直接使用采集類庫現(xiàn)采現(xiàn)顯。
總結(jié):
優(yōu)點(diǎn)是:不用和數(shù)據(jù)庫打交道,現(xiàn)采現(xiàn)顯,減少數(shù)據(jù)庫壓力,速度快,每天只采一次,丁點(diǎn)信息,緩存即可。對(duì)于天氣只是裝飾性的極適用。
缺點(diǎn)是:數(shù)據(jù)量少,不能做能專業(yè)性天氣預(yù)報(bào)站。
以下介紹現(xiàn)采現(xiàn)顯的實(shí)現(xiàn)方式
1:既然要采,當(dāng)然找到有天氣預(yù)報(bào)的站了,這個(gè)很好找,網(wǎng)上到處都是資源,只要你會(huì)采。
比如百度,你搜索城市如廣州,即會(huì)出現(xiàn)天氣信息了,如圖:
比如騰訊soso,如下圖。當(dāng)然還有其它很多很多,只要看得到的,都可以采,不過最好找大站,穩(wěn)定。
2:采集類,一個(gè)好的采集類,事半功倍,以下出一個(gè)簡(jiǎn)化版,足夠采集天氣信息
usingSystem;
usingSystem.Text;
usingSystem.Net;
usingSystem.Text.RegularExpressions;
namespaceCYQ.Tool
{
///<summary>
///作者:路過秋天
///博客:http://cyq1162.cnblogs.com
///</summary>
publicclassGatherHelper
{
///<summary>
///返回獲取的目標(biāo)地址HTML全部代碼
///</summary>
///<paramname="strUrl">目標(biāo)地址</param>
///<returns></returns>
publicstaticstringGetHtmlCode(stringpageUrl,Encodingencoding)
{
try
{
//返回目標(biāo)頁HTML代碼
WebClientwebclient=newWebClient();
webclient.Credentials=CredentialCache.DefaultCredentials;
byte[]buffer=webclient.DownloadData(pageUrl);
stringHtmlCode=encoding.GetString(buffer);
webclient.Dispose();//釋放WebClient資源
returnHtmlCode;
}
catch
{
returnstring.Empty;
}
}
#region內(nèi)容截取分析
///<summary>
///返回根據(jù)內(nèi)容開始及結(jié)束代碼分析出內(nèi)容
///</summary>
///<paramname="ContentCode">內(nèi)容代碼</param>
///<paramname="StartCode">內(nèi)容所在開始代碼</param>
///<paramname="EndCode">內(nèi)容所在結(jié)束代碼</param>
///<paramname="index">取第幾條[從1開始]</param>
///<returns></returns>
publicstaticstringGetContent(stringcontentCode,stringstartCode,stringendCode,intindex)
{
string[]matchItems=null;
returnGetContent(contentCode,startCode,endCode,index,outmatchItems);
}
publicstaticstringGetContent(stringcontentCode,stringstartCode,stringendCode,intindex,outstring[]matchItems)
{
matchItems=null;
if(string.IsNullOrEmpty(startCode)&&string.IsNullOrEmpty(endCode))
{
returncontentCode;
}
RegexregObj=newRegex(startCode+@"([\S\s]*?)"+endCode,RegexOptions.Compiled|RegexOptions.IgnoreCase);
MatchCollectionmatchItemList=regObj.Matches(contentCode);
if(matchItemList!=null&&matchItemList.Count>=index)
{
matchItems=newstring[matchItemList.Count];
for(inti=0;i<matchItemList.Count;i++)
{
matchItems[i]=matchItemList[i].Groups[1].Value;
}
index=index>0?index-1:0;
returnmatchItemList[index].Groups[1].Value;
}
returnstring.Empty;
}
#endregion
}
}
3:編寫天氣預(yù)報(bào)實(shí)體類,將采集的信息以實(shí)體返回,如果采集多個(gè),返回就是List<實(shí)體>了
publicclassWeatherInfo
{
privatestringimgUrl;
///<summary>
///天氣圖片地址
///</summary>
publicstringImgUrl
{
get{returnimgUrl;}
set{imgUrl=value;}
}
privatestringwind;
///<summary>
///天氣風(fēng)力
///</summary>
publicstringWind
{
get{returnwind;}
set{wind=value;}
}
privatestringcityName;
///<summary>
///天氣城市名稱
///</summary>
publicstringCityName
{
get{returncityName;}
set{cityName=value;}
}
privatestringtemperature;
///<summary>
///天氣溫度
///</summary>
publicstringTemperature
{
get{returntemperature;}
set{temperature=value;}
}
privatestringdescription;
///<summary>
///天氣說明
///</summary>
publicstringDescription
{
get{returndescription;}
set{description=value;}
}
4:編寫采集Soso的天氣預(yù)報(bào)類
A:新建采集天氣預(yù)報(bào)類:WeatherSearch
///<summary>
///作者:路過秋天
///博客:http://cyq1162.cnblogs.com
///</summary>
publicclassWeatherSearch
{
///<summary>
///數(shù)據(jù)采集來源于騰信搜搜天氣預(yù)報(bào)
///</summary>
///<paramname="cityName"></param>
///<returns></returns>
publicstaticWeatherInfoGet(stringcityName)
{
//待實(shí)現(xiàn)
}
privatestaticWeatherInfoGetFormCache(stringcityName,stringkey)
{
objectweather=HttpContext.Current.Cache.Get(key);
if(weather!=null)
{
returnweatherasWeatherInfo;
}
returnnull;
}
}
重要說明:
采集一次后,記得緩存起來,不然每次訪問都現(xiàn)采,刷刷就被soso給封了,切身經(jīng)歷啊。
B:Get函數(shù)分解:
1:先讀取緩存,注意緩存Key用日期做key,可以方便緩存今天和刪除昨天的緩存。
publicstaticWeatherInfoGet(stringcityName)//中文城市名稱
{
if(string.IsNullOrEmpty(cityName))
{
returnnull;
}
stringtodayKey=cityName+DateTime.Now.ToString("yyyyMMdd");
WeatherInfoweather=GetFormCache(cityName,todayKey);
if(weather==null)
{
//待實(shí)現(xiàn)
}
}
2:讀不到緩存就現(xiàn)采了,調(diào)用采集類
if(weather==null)
{
weather=newWeatherInfo();
weather.CityName=cityName;
cityName=System.Web.HttpUtility.UrlEncode(cityName+"天氣",Encoding.GetEncoding("gb2312"));
stringurl="http://www.soso.com/q?num=1&w="+cityName;
//采集所有html
stringhtml=GatherHelper.GetHtmlCode(url,Encoding.GetEncoding("gb2312"));
//接下來待實(shí)現(xiàn)
}
說明:
這里城市要用中文編碼傳過去,至于url,是我發(fā)現(xiàn)的最簡(jiǎn)潔的參數(shù),現(xiàn)在已把搜搜的搜索頁面的全html抓回來了,接下來就是分離出想要的信息。
3:分析html,縮小范圍,對(duì)于一大堆html,我們只要這一部分
<!--上面的被省略-->
<divclass="w_main">
<ol>
<liclass="w_space"title="北風(fēng)4-5級(jí)"><span>今天(周五)</span>
<imgsrc="http://cache.soso.com/zdq/wea/s_a3.png"onload="setPng(this,48,48)"/>
<span>21/28<em>°</em>C</span><spanclass="w_w">多云轉(zhuǎn)陣雨</span></li>
<lititle="北風(fēng)3-4級(jí)"><span>明天(周六)</span>
<imgsrc="http://cache.soso.com/zdq/wea/s_a3.png"onload="setPng(this,48,48)"/>
<span>22/28<em>°</em>C</span><spanclass="w_w">多云轉(zhuǎn)陣雨</span></li>
<lititle="微風(fēng)"><span>后天(周日)</span>
<imgsrc="http://cache.soso.com/zdq/wea/s_a33.png"onload="setPng(this,48,48)"/>
<span>18/29<em>°</em>C</span><spanclass="w_w">多云</span></li>
</ol>
</div>
<!--下面的也被省略-->
說明:
我們使用GetContent方法可以非常方便的縮小范圍,只要找到唯一的起始標(biāo)簽和結(jié)束標(biāo)簽,不會(huì)正則,也一樣截取。
4:使用GetContent步步截取所需要信息
if(string.IsNullOrEmpty(html)){returnnull;}
//縮小范圍
html=GatherHelper.GetContent(html,"<divclass=\"w_main\">","</div>",1);
if(string.IsNullOrEmpty(html)){returnnull;}
//說明
weather.Description=GatherHelper.GetContent(html,"<spanclass=\"w_w\">","</span>",1);
//圖片
weather.ImgUrl=GatherHelper.GetContent(html,"<imgsrc=\"","\"",1);
//風(fēng)向
weather.Wind=GatherHelper.GetContent(html,"title=\"","\"",1);
//溫度
weather.Temperature=GatherHelper.GetContent(html,"/><span>","<em>",1);
5:存入緩存并清除昨天的緩存信息[看需要展示幾天的信息了]
HttpContext.Current.Cache.Insert(todayKey,weather);
stringyesterdayKey=cityName+DateTime.Now.AddDays(-1).ToString("yyyyMMdd");
if(HttpContext.Current.Cache.Get(yesterdayKey)!=null)
{
HttpContext.Current.Cache.Remove(yesterdayKey);
}
5:界面調(diào)用
protectedvoidPage_Load(objectsender,EventArgse)
{
WeatherInfoinfo=WeatherSearch.Get("廣州");
if(info!=null)
{
litCity.Text=info.CityName;
litDescprtion.Text=info.Description;
imgUrl.ImageUrl=info.ImgUrl;
litWind.Text=info.Wind;
litTemperature.Text=info.Temperature;
}
}
6:調(diào)用結(jié)果
最后結(jié)言:
本博沒有快速評(píng)論通道,大伙積極點(diǎn)下手。
再不濟(jì)手動(dòng)復(fù)制-》“此文不錯(cuò),值的推薦”!!
-_-...!!!
IE6好卡,鼠標(biāo)又發(fā)神經(jīng),單擊雙擊混在一起,本文寫起來好辛苦~~
本文示例下載地址:CYQ.Data 輕量數(shù)據(jù)層之路 bug反饋、優(yōu)化建議、最新框架下載
|
版權(quán)聲明:本文原創(chuàng)發(fā)表于 博客園,作者為 路過秋天 本文歡迎轉(zhuǎn)載,但未經(jīng)作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則視為侵權(quán)。 |
|
個(gè)人微信公眾號(hào) |
創(chuàng)業(yè)QQ群:617713515 |
Donation(掃碼支持作者):支付寶: |
Donation(掃碼支持作者):微信: |
總結(jié)
以上是生活随笔為你收集整理的实战系列之天气预报实时采集的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python字符串输入_python如何
- 下一篇: 在线代码托管平台 GitHub 增强 A