• 天气预报抓取的方法和源代码(包括从IP获取)


     前段时间在公司系统(电联协同管理软件)中需要天气预报信息。据此就写了一个天气预报抓取的类。今天说一下我抓取的思路和方法,并共享一下源代码。
      刚开始做的时候,在网上找了一下代码。发现WebXml.com.cn上面有直接可调用的webServices地址为http://webservice.webxml.com.cn/WebServices/WeatherWS.asmx。不过他对免费调用的用户有一定限制,请看http://www.webxml.com.cn/zh_cn/web_services_user.aspx。所以我打算自己写。
      我发现很多网站包括WebXml都是从中国天气网(http://www.weather.com.cn/)抓取的。经过分析,发现可以有2总方法或去数据:
      1.直接掉用它的JS获取数据的方式。
      这种方法获取简单,但数据量不多。
      它本身就一个地址可直接获取JSON数据:http://m.weather.com.cn/data/天气代码.html。获取到的数据如下:
    {"weatherinfo":{"city":"北京","date_y":"2009年7月22日","date":"六月初一","week":"星期三","fchh":"08","cityid":"101010100","temp1":"33℃~24℃","temp2":"27℃~20℃","temp3":"31℃~21℃","temp4":"35℃~21℃","weather1":"阴转雷阵雨","weather2":"雷阵雨转阵雨","weather3":"多云","weather4":"","img1":"2","img2":"4","img3":"4","img4":"3","img5":"1","img6":"99","img7":"0","img8":"99","img_single":"2","img_title1":"","img_title2":"雷阵雨","img_title3":"雷阵雨","img_title4":"阵雨","img_title5":"多云","img_title6":"多云","img_title7":"","img_title8":"","img_title_single":"","wind1":"微风","wind2":"微风","wind3":"微风","wind4":"微风","fl1":"小于3级","fl2":"小于3级","fl3":"小于3级","fl4":"小于3级","index":"炎热","index_d":"天气炎热,建议着短衫、短裙、短裤、薄型T恤衫、敞领短袖棉衫等清凉夏季服装。","index_uv":"","index_xc":"不宜","index_tr":"较不宜","index_co":"较不舒适"}}


      要获取他,先建立一个实体类WeatherSimpleInfo:

    /// <summary>简单天气实体</summary>
        public class WeatherSimpleInfo
        {
            
    /// <summary>城市</summary>
            public string city { getset; }
            
    /// <summary>时间</summary>
            public string date_y { getset; }
            
    /// <summary>农历时间</summary>
            public string date { getset; }
            
    /// <summary>ID</summary>
            public string cityid { getset; }
            
    /// <summary>温度</summary>
            public string temp1 { getset; }

            
    public string temp2 { getset; }
            
    /// <summary>天气</summary>
            public string weather1 { getset; }
            
    public string weather2 { getset; }
            
    /// <summary>图片</summary>
            public string img1 { getset; }
            
    public string img2 { getset; }
            
    public string img3 { getset; }
            
    public string img4 { getset; }
            
    /// <summary></summary>
            public string wind1 { getset; }
            
    public string wind2 { getset; }
            
    /// <summary>穿衣简单指数</summary>
            public string index { getset; }
            
    /// <summary>穿衣指数</summary>
            public string index_d { getset; }
            
    /// <summary>紫外线简单指数</summary>
            public string index_uv { getset; }
            
    /// <summary>洗车简单指数</summary>
            public string index_xc { getset; }
            
    public string index_tr { getset; }

            
    public override string ToString()
            {
                var sb 
    = new StringBuilder();
                sb.AppendFormat(
    "城市:{0}\r\n"this.city);
                sb.AppendFormat(
    "时间:{0}\r\n"this.date_y);
                sb.AppendFormat(
    "天气:{0}\r\n"this.weather1);
                sb.AppendFormat(
    "温度:{0}\r\n"this.temp1);
                sb.AppendFormat(
    "风:{0}\r\n"this.wind1);
                sb.AppendFormat(
    "穿衣指数:({0})。{1}\r\n"this.index, this.index_d);
                sb.AppendFormat(
    "紫外线指数:{0}\r\n"this.index_uv);
                sb.AppendFormat(
    "洗车指数:{0}\r\n"this.index_xc);
                
    return sb.ToString();
            }
        }


       抓取类:WeatherSimple: 

    /// <summary>简单天气预报数据操作(直接从JSON获取)</summary>
     public class WeatherSimple
     {
      
      
    private const string __Url = "http://m.weather.com.cn/data/{0}.html";
      
    public WeatherSimple() { }
      
    public WeatherSimpleInfo weatherinfo { getset; }
      
    /// <summary>获取简单天气预报</summary>
      
    /// <param name="name">城市代码</param>
      
    /// <returns>天气预报</returns>
      public static WeatherSimpleInfo Get(string code)
      {
       
    using(WebClient wc = new WebClient()){
        wc.Encoding 
    = Encoding.UTF8;
        var url
    =string.Format(__Url,code);
        
    string str = wc.DownloadString(url);
        
    return SerializationHelper.JsonDeserialize<WeatherSimple>(str).weatherinfo;
       }
      }
     }


       2.抓取Html并分析提取数据的方式。
       这种方法获取复杂,但可以获取较多天气数据。
      天气网的http://www.weather.com.cn/html/weather/天气代码.shtml地址可以显示相关地区的天气信息。
      用WebClient抓取数据后提取。很多人提取数据是使用正则表达式的方式,不过本人正则表达式用的比较烂,就选择XML的方式了。
      众所周知,html本身是不标准的xml。不能直接通过XmlDocumentl来读取。这里我借助了SgmlReaderDll。他可以把Html转换成xml。
      转换成功后我们就可以用xpath的方式来提取数据了,更具需求还可以提取不同的天气指数。具体提取请看原代码。
     这样就完成了天气预报的提取。但这还不够,还必须有获取城市代码的方法.
     获取城市代码可以直接使用http://www.weather.com.cn/data/listinfo/city上级城市代码.xml。去获取到的数据如下
     01|北京,02|上海,03|天津,04|重庆,05|黑龙江,06|吉林,07|辽宁
     我们可以通过Split他提取成包括名称和代码的城市数组。
     有了城市代码后我们还需要通过城市名称获取代码的方法,所以我把它的所有城市和代码都下载到WeatherCity.Xml文件内了。见原代码。
      按照公司的需求,还要有通过访问者IP获取天气的功能。这里我就想到了纯真IP库。用它直接获取IP所在的城市,但纯真IP库里面的城市是比较复杂的,他包括县、城市、区、甚至某个网吧的信息。这里我们要分析他,具体代码如下

    /// <summary>更具IP获取城市代码</summary>
            
    /// <param name="ipDataPath">IP库地址</param>
            
    /// <param name="ip">IP地址</param>
            
    /// <returns>城市代码</returns>
      public static string GetCityCodeByIp(string ipDataPath,string ip){
       IPLocation.IPLocation.IPLocate(ipDataPath,ip);
       var country 
    = IPLocation.IPLocation.Country;
       var regex 
    = new Regex("([^市省]+)市");
       var match
    =regex.Match(country);
       var area
    =string.Empty;
       var province 
    = string.Empty;
       var city 
    = string.Empty;
       var matCity 
    = Regex.Matches(country, "([^市省]+)市");
       var matArea 
    = Regex.Matches(country, "([^市省区]+)区");
       var matProvince 
    = Regex.Matches(country, "([^省]+)省");
       
    if(matArea.Count>0){
        area 
    = matArea[0].Result("$1");
       }
       
    if (matProvince.Count > 0)
       {
        province 
    = matProvince[0].Result("$1");
       }
       
    if (matCity.Count > 0)
       {
        city 
    = matCity[matCity.Count - 1].Result("$1");
       }
       var code
    =string.Empty;
       
    if (!string.IsNullOrEmpty(area))
       {
        code 
    = GetCityCodeByName(area);
        
    if (!string.IsNullOrEmpty(code))
        {
         
    return code;
        }
       }
       
    if (!string.IsNullOrEmpty(city))
       {
        code 
    = GetCityCodeByName(city);
        
    if (!string.IsNullOrEmpty(code))
        {
         
    return code;
        }
       }
       
    if (!string.IsNullOrEmpty(province))
       {
        code 
    = GetCityCodeByName(province);
        
    if (!string.IsNullOrEmpty(code))
        {
         
    return code;
        }
       }
       
    if (string.IsNullOrEmpty(code)){
        code 
    = GetCityCodeByName(country.Substring(02));
        
    if (!string.IsNullOrEmpty(code))
        {
         
    return code;
        }
       }
       
    return string.Empty;
      }

     如此整个天气预报获取就完成了,请下载代码Flashado.Weather.WInForm工程是测试程序,下载后大家可直接用它测试。

     天气预报源代码 http://www.dyinfor.com/files/Flashado.Weather.rar

    转:http://www.cnblogs.com/ailiangwu/archive/2009/07/22/1528342.html

  • 相关阅读:
    使用尾递归对斐波那契优化?
    Ajax是什么?包含什么技术?有什么作用?
    Ajax的乱码解决问题?
    Ajax的核心的对象是什么?
    为什么Java中不支持多重继承?
    vue-router的原理,例如hashhistory和History interface?
    JSP是什么?有什么特点?
    forward 和redirect的区别?
    Listener是什么?有什么作用?
    请说一说Servlet的生命周期?
  • 原文地址:https://www.cnblogs.com/liuhaitao/p/1528518.html
Copyright © 2020-2023  润新知