访问www.163.com,首页的栏目里有当地的天气预告。可以猜想,这里的天气预告,应该是根据来访者的ip判定其所在地给出当地的天气情况。问了一些朋友,也证实了这一点。项目里也需要天气预告这个小栏目,同事做过一个(从其他站点抓取的),不过实现不了根据IP显示当地的天气情况,需要用户自行选择,而且抓取的站点属于小站….其可靠性值得怀疑。。所以就萌生了抓取网易的天气预告的想法。。。对页面进行分析。。发现显示天气预告的区域是一个IFrame,IFrame里嵌入了如下链接http://news.163.com/util/position1.html, 对这个地址访问直接跳转到另外一个链接http://news.163.com/weather/news/qx1/56294.html,此链接显示了天气情况,如图

由此可以推测http://news.163.com/util/position1.html,是在根据来访者的IP判定所属区域,然后返回一个该地区所对应的区位码,如: 56294代表成都。如何让网易来帮我们的站点来访者判定所属区域,并给出天气情况,并显示在自己的站点页面上呢?还得继续分析。。因为http://news.163.com/util/position1.html,此链接一访问就转向到天气情况的链接,而无法查看源码。便猜想。。此页面肯定有些东西。。无奈之下。。WebRequest一下,出现了如下代码:
以下是引用片段
1%26lt;scriptlanguage="Javascript"%26gt;
2varcity=newArray("安徽","黑龙江","山东","北京","湖北","山西","福建","湖南","陕西","甘肃","吉林","上海","广东","江苏","四川","广西","江西","天津","贵州","辽宁","西藏","海南","内蒙古","新疆","河北","宁夏","云南","河南","青海","浙江","重庆");
3varweaths=newArray('58321','50953','54823','54511','57494','53772','59134','57679','57036','52889','54172','58367','59287','58238','56294','59431','58606','54527','57816','54342','55591','52856','53463','51463','53698','53614','56778','57083','52866','58457','57516');
4
5functiongetCookieVal(offset){
6varendstr=document.cookie.indexOf(";",offset);
7if(endstr==-1)
8endstr=document.cookie.length;
9returnunescape(document.cookie.substring(offset,endstr));
10}
11functionGetCookie(name){
12vararg=name+"=";
13varalen=arg.length;
14varclen=document.cookie.length;
15vari=0;
16while(i%26lt;clen){
17varj=i+alen;
18if(document.cookie.substring(i,j)==arg)
19returngetCookieVal(j);
20i=document.cookie.indexOf("",i)+1;
21if(i==0)
22break;
23}
24return"";
25}
26functionSetCookie(cookieName,cookieValue,nDays){
27vartoday=newDate();
28varexpire=newDate();
29if(nDays==null||nDays==0)nDays=1;
30expire.setTime(today.getTime()+3600000*24*nDays);
31document.cookie=cookieName+"="+escape(cookieValue)+";path=/;domain=.163.com;expires="+expire.toGMTString();
32}
33functiongetCityWeatherID(cityname){
34for(i=0;i%26lt;city.length;i++){
35if(city[i]==cityname){
36returnweaths[i];
37}
38}
39return"54511";
40}
41
42varNTES_WeatherAddr=GetCookie("NTES_WeatherAddr");
43if(!NTES_WeatherAddr){
44varloc=GetCookie("theaddr");
45if(!loc){
46document.write("%26lt;scripttype='text/javascript'src='http://202.108.39.152/ipquery'%26gt;%26lt;"+"/script%26gt;");
47}
48}
49%26lt;/script%26gt;
50%26lt;script%26gt;
51if(!NTES_WeatherAddr){
52NTES_WeatherAddr=getCityWeatherID(loc);
53}
54window.location.href="http://news.163.com/weather/news/qx1/"+NTES_WeatherAddr+".html";
55%26lt;/script%26gt;
56
57
上面的这段js实现了对来访者IP判定并给出了天气预告结果的链接。Js里的此链接: http://202.108.39.152/ipquery,起到的是判定用户所在地的作用,返回的是来访者所在地省份。分析到此,想要的结果差不多就出来了…
在客户端调用这段js获得天气预告结果的链接地址,然后交给服务端来处理。(为什么要交给后台处理,而不是直接显示呢?)因为直接得出的链接页面上,有多余的链接,还应用了样式(如图一),不便为自己所用,所以得处理掉。客户端调用服务端的方法很多,最初使用了Ajax框架Anthem,实现了过后,觉得有点杀鸡用牛刀的感觉。。无聊之余。。就又用CallBack实现了一次。。感觉恰到好处。。后来又发现。。__doPostBack也可以实现客户端调用服务端方法。。看来实现这么一个功能还真是简单。。。
好了到此就实现了,自己想要的结果:(感觉有点遗憾的是只给出了省会城市的天气预告)

前台页面代码Defaul.aspx:
以下是引用片段
1%26lt;%@PageLanguage="C#"AutoEventWireup="true"CodeFile="Default.aspx.cs"Inherits="_Default"ResponseEncoding="GB2312"%%26gt;
2%26lt;!DOCTYPEhtmlPUBLIC"-//W3C//DTDXHTML1.0Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"%26gt;
3%26lt;htmlxmlns="http://www.w3.org/1999/xhtml"%26gt;
4%26lt;headrunat="server"%26gt;
5%26lt;title%26gt;%26lt;/title%26gt;
6%26lt;script%26gt;
7varcity=newArray("安徽","黑龙江","山东","北京","湖北","山西","福建","湖南","陕西","甘肃","吉林","上海","广东","江苏","四川","广西","江西","天津","贵州","辽宁","西藏","海南","内蒙古","新疆","河北","宁夏","云南","河南","青海","浙江","重庆");
8varweaths=newArray('58321','50953','54823','54511','57494','53772','59134','57679','57036','52889','54172','58367','59287','58238','56294','59431','58606','54527','57816','54342','55591','52856','53463','51463','53698','53614','56778','57083','52866','58457','57516');
9
10varNTES_WeatherAddr=GetCookie("NTES_WeatherAddr");
11if(!NTES_WeatherAddr){
12varloc=GetCookie("theaddr");
13if(!loc){
14document.write("%26lt;scripttype='text/javascript'src='http://202.108.39.152/ipquery'%26gt;%26lt;"+"/script%26gt;");
15}
16}
17
18functiongetCookieVal(offset){
19varendstr=document.cookie.indexOf(";",offset);
20if(endstr==-1)
21endstr=document.cookie.length;
22returnunescape(document.cookie.substring(offset,endstr));
23}
24
25functionGetCookie(name){
26vararg=name+"=";
27varalen=arg.length;
28varclen=document.cookie.length;
29vari=0;
30while(i%26lt;clen){
31varj=i+alen;
32if(document.cookie.substring(i,j)==arg)
33returngetCookieVal(j);
34i=document.cookie.indexOf("",i)+1;
35if(i==0)
36break;
37}
38return"";
39}
40
41functionSetCookie(cookieName,cookieValue,nDays){
42vartoday=newDate();
43varexpire=newDate();
44if(nDays==null||nDays==0)nDays=1;
45expire.setTime(today.getTime()+3600000*24*nDays);
46document.cookie=cookieName+"="+escape(cookieValue)+";path=/;domain=.163.com;expires="+expire.toGMTString();
47}
48
49//根据Ip服务器返回的省份名称获取对应的编号
50functiongetCityWeatherID(cityname){
51for(i=0;i%26lt;city.length;i++){
52if(city[i]==cityname){
53returnweaths[i];
54}
55}
56return"57816";
57}
58
59//获取所在地天气预告结果的链接
60functiongetWeatherUrl(){
61if(!NTES_WeatherAddr){
62NTES_WeatherAddr=getCityWeatherID(loc);
63
64}
65varaddr="http://news.163.com/weather/news/qx1/"+NTES_WeatherAddr+".html";
66document.form1.Text1.value=addr;
67}
68
69//客户端调用服务端方法实现对天气预告结果链接的页面内容进行解析,Anthem实现方式
70functionshowWeatherByAnthem(){
71Anthem_InvokePageMethod("ShowWeatherByAnthem",[],getServerResult);
72}
73
74functiongetServerResult(result){
75document.getElementById("result").innerHTML=result.value;
76}
77
78//客户端调用服务端方法实现对天气预告结果链接的页面内容进行解析,_doPostBack实现方式
79functionshowWeatherBylink()
80{
81__doPostBack('LinkButton1','');
82}
83
84//客户端调用服务端方法实现对天气预告结果链接的页面内容进行解析,CallBack实现方式
85functionshowWeatherByCallBack()
86{
87varcontext=document.getElementById("result");
88varweatherUrl=document.getElementById("Text1");
89vararg="ShowWeatherByCall|"+weatherUrl.value;
90%26lt;%=ClientScript.GetCallbackEventReference(this,"arg","outPutResult","context")%%26gt;;
91}
92functionoutPutResult(result)
93{
94document.getElementById("result").innerHTML=result;
95
96}
97%26lt;/script%26gt;
98%26lt;/head%26gt;
99%26lt;bodyonload="getWeatherUrl(),showWeatherByCallBack()"%26gt;
100%26lt;formid="form1"runat="server"%26gt;
101%26lt;spanid="result"%26gt;%26lt;/span%26gt;
102%26lt;inputid="Text1"type="hidden"runat="server"/%26gt;
103%26lt;/form%26gt;
104%26lt;/body%26gt;
105%26lt;/html%26gt;
106
后台代码Default.cs:
以下是引用片段
1usingSystem;
2usingSystem.Data;
3usingSystem.Configuration;
4usingSystem.Web;
5usingSystem.Web.Security;
6usingSystem.Web.UI;
7usingSystem.Web.UI.WebControls;
8usingSystem.IO;
9usingSystem.Net;
10usingAnthem;
11
12publicpartialclass_Default:System.Web.UI.Page,ICallbackEventHandler
13{
14protectedvoidPage_Load(objectsender,EventArgse)
15{
16Anthem.Manager.Register(this);
17
18}
19
20回调的固定格式#region回调的固定格式
21publicstringstr_content;
22
23publicvoidRaiseCallbackEvent(stringthe_string)
24{
25str_content=the_string;
26}
27
28/**////%26lt;summary%26gt;
29///回调,解析客户端的参数
30///%26lt;/summary%26gt;
31///%26lt;returns%26gt;%26lt;/returns%26gt;
32publicstringGetCallbackResult()
33{
34
35string[]parts=str_content.Split('|');
36object[]theArgList=newobject[parts.Length-1];
37for(intint_index=1;int_index%26lt;parts.Length;int_index++)
38theArgList[int_index-1]=parts[int_index];
39return(string)GetType().GetMethod(parts[0]).Invoke(this,theArgList);
40}
41#endregion
42
43解析url的页面内容的方法体#region解析url的页面内容的方法体
44/**////%26lt;summary%26gt;
45///Anthem方式,解析获取的url的页面内容
46///%26lt;/summary%26gt;
47///%26lt;paramname="url"%26gt;url%26lt;/param%26gt;
48///%26lt;returns%26gt;解析结果%26lt;/returns%26gt;
49[Anthem.Method]
50publicstringShowWeatherByAnthem()
51{
52
53WebRequestrequest=WebRequest.Create(Text1.Value);
54request.Credentials=CredentialCache.DefaultCredentials;
55HttpWebResponseresponse=(HttpWebResponse)request.GetResponse();
56StreamdataStream=response.GetResponseStream();
57StreamReaderreader=newStreamReader(dataStream,System.Text.Encoding.Default);
58stringstr=reader.ReadToEnd();
59returnstr.Substring(220);
60
61}
62//%26lt;summary%26gt;
63//回调方式,解析获取的url的页面内容
64//%26lt;/summary%26gt;
65//%26lt;paramname="url"%26gt;%26lt;/param%26gt;
66//%26lt;returns%26gt;%26lt;/returns%26gt;
67publicstringShowWeatherByCall(stringurl)
68{
69WebRequestrequest=WebRequest.Create(url);
70request.Credentials=CredentialCache.DefaultCredentials;
71HttpWebResponseresponse=(HttpWebResponse)request.GetResponse();
72StreamdataStream=response.GetResponseStream();
73StreamReaderreader=newStreamReader(dataStream,System.Text.Encoding.Default);
74stringstr=reader.ReadToEnd();
75returnstr.Substring(220);
76
77}
78#endregion
79}
80
