java 获得天气预报信息

来源:互联网 发布:单片机与电脑usb连接 编辑:程序博客网 时间:2024/05/16 04:45

java 获得天气预报信息


最近项目中需要增加天气预报功能,网上给的资料有很多缺陷比如

1.       有些小网站提供的webservers本身就不稳定不能长期使用。

2.       还有一些网站限制访问次数。

3.       再有就是花钱买服务。

 

根据以上几点只能放弃使用第三方的webservers,由此我们只能找个信得过的提供天气预报的网站抓取页面信息。

接下来我们以中央气象台为例实现从请求到数据解析的过程。

 

1.       浏览http://www.nmc.gov.cn/ 发现一个搜索功能

 

做过网页的人都知道通过表单提交城市名字,那我们去看看具体提交到什么地方呢。

 

在这个from表单中我们发现了什么?对有action 和 keys 这都知道是什么意思我就不废话了。

最终我们得到一个url : http://www.nmc.gov.cn/search_result.php?keys=城市名字

哈哈,这就是我们获得天气预报的关键。

 

2.       通过程序访问url.

以下是使用HttpClient的例子

HttpClient client = new HttpClient();//实例

String url="http://www.nmc.gov.cn//search_result.php?keys="+city;

method =  new GetMethod(url);//通过Get方式访问

httpstatus = client.executeMethod(method);

if(httpstatus==200)//200表示成功

{

//获得响应转码为GBK,否则中文会乱码

String  result=newString

(method.getResponseBodyAsString().getBytes("iso-8859-1"),"GBK");

}

 

用上面的程序访问你会发现报错了 Invalid query  ;这里我们需要将城市名字转码

 

String url="http://www.nmc.gov.cn//search_result.php?

keys="+URLEncoder.encode(city,”GBK”);

 

这样在url中中文就是转码后的不会出现乱码。

 

3.       解析数据

以北京为例提交后网页信息为:

 

 

对应的页面中的代码为:

 

至此我们就可以获得天气信息了。。。。解析的代码如下:

 

        public  void ParaseHtml(String html)

    {

 

       String climate = ParaseWeatherInfo(html,"天气");

       String temperature = ParaseWeatherInfo(html,"气温");

       String wind = ParaseWeatherInfo(html,"风");

       String barometric = ParaseWeatherInfo(html,"气压");

      

       log.debug("天气:"+climate +"/ 气温 :"+temperature +"/ 风 "+wind +"/ 气压"+barometric);

    }

    public  String ParaseWeatherInfo(String str,String word)

    {

       String w = null;

       String st = "w365line1";

       //System.err.println(str);

       int a = str.indexOf(st);

       if(a!= -1)

       {

           String div1 = "<div";

           String div2 = "</div>";

           String keyword = ":";

           int d1 = str.lastIndexOf(div1, a);

           int d2 = str.indexOf(div2, a);

           if(d2 != -1)

           {

              String str4 = null;

              String str2 = str.substring(d1, d2+div2.length());

              if(str2.indexOf(word) !=-1)

              {

                  str4 = filerStr(str2,word,"");

                  int k1 = str4.indexOf(keyword);

                  str4 = str4.substring(k1+1,str4.length()).trim();

                  return str4;

              }  

              else

              {

                  String s5 = str.replace(str2, "");

                  w = ParaseWeatherInfo(s5,word);

                  return w;

              }

           }

       }

      

       return w;

    }

    public  String filerStr(String html,String word,String replacement)

    {   

    try{

        if(replacement==null)

            replacement = "";

        String   str=html; 

            String   str1="(<[^>]*>)|(&nbsp;)"; 

            Pattern   p=Pattern.compile(str1); 

            Matcher   m=p.matcher(str); 

            boolean   f=m.find(); 

            StringBuffer   sb=new   StringBuffer();  

            while(f)   { 

          

                m.appendReplacement(sb,replacement); 

                f=m.find(); 

            } 

            m.appendTail(sb);

           

            return sb.toString();

       

    }

    catch(Exception e)

    {

       

    }

   

    return html;

    }

 

抓取北京的天气信息:

       String html = WeatherUtil2.getInstance().getNMCRespones("北京");

       WeatherUtil2.getInstance().ParaseHtml(html);

 

天气:多云/ 气温 :30 ℃/ 风 西南风,3级,4米/秒/ 气压1001.8hPa

 
 
===================
java 获取天气预报实现代码

最简单的办法是申请一个yahoo dev 的key ,然后就可以通过 GeoPlanet api 来查询相应地点的WOEID了。用的是旧的p 参数传递地点代码,不过最新的api文档里面只对w参数作了

说明,因此这里我就用WOEID了。不想注册申请key,还是自己折腾吧。下载最新的 GeoPlanet Data ,解压出来有这些个文件:geoplanet_places_[version].tsv: the WOEID, the

placename, and the WOEID of its parent entitygeoplanet_aliases_[version].tsv: alternate names in multiple languages indexed against the

WOEIDgeoplanet_adjacencies_[version].tsv: the entities neighboring each WOEIDgeoplanet_changes_[version].tsv: the list of removed WOEIDs and their

replacement WOEID mappings
 这里我只取 geoplanet_places_7.6.0.tsv ,用EmEditor 打开,把 中国 地区的 COPY 出到另外一个文件Chinaplaces.tsv .
这个tsv 文件是用tab分隔字段的,places文件的字段有:WOE_ID ISO Name Language PlaceType Parent_ID
 
public static HashMap<String, String> cityCode = new HashMap<String, String>();    /* 初始化城市代号 */private void initCitys() {    cityCode.put("北京",

"0008");    cityCode.put("天津", "0133");    cityCode.put("武汉", "0138");    cityCode.put("杭州", "0044");    cityCode.put("合肥 ", "0448");   

cityCode.put("上海 ", "0116");    cityCode.put("福州 ", "0031");    cityCode.put("重庆 ", "0017");    cityCode.put("南昌 ", "0097");    cityCode.put("香港 ",

"0049");    cityCode.put("济南 ", "0064");    cityCode.put("澳门 ", "0512");    cityCode.put("郑州 ", "0165");    cityCode.put("呼和浩特 ", "0249");   

cityCode.put("乌鲁木齐 ", "0135");    cityCode.put("长沙 ", "0013");    cityCode.put("银川 ", "0259");    cityCode.put("广州 ", "0037");    cityCode.put("拉

萨 ", "0080");    cityCode.put("海口 ", "0502");    cityCode.put("南京 ", "0100");    cityCode.put("成都 ", "0016");    cityCode.put("石家庄 ", "0122");   

cityCode.put("贵阳 ", "0039");    cityCode.put("太原 ", "0129");    cityCode.put("昆明 ", "0076");    cityCode.put("沈阳 ", "0119");    cityCode.put("西安 ",

"0141");    cityCode.put("长春 ", "0010");    cityCode.put("兰州 ", "0079");    cityCode.put("西宁 ", "0236");}

  
--------------------------------------------------------------------------------
接下来我们要创建链接,以获取天气预报的XML文档

private Document getWeatherXML(String cityCode) throws IOException {        URL url = new URL("http://weather.yahooapis.com/forecastrss?p=CHXX"              

 + cityCode + "&u=c");        URLConnection connection = url.openConnection();        Document Doc = stringToElement(connection.getInputStream());       

return Doc;    }

  
--------------------------------------------------------------------------------
您也可以选择保存获取的天气XML文档

/* 保存获取的天气信息XML文档 */    private void saveXML(Document Doc, String Path) {        TransformerFactory transFactory = TransformerFactory.newInstance

();        Transformer transformer;        try {            transformer = transFactory.newTransformer();            DOMSource domSource = new DOMSource(Doc);

           File file = new File(Path);            FileOutputStream out = new FileOutputStream(file);            StreamResult xmlResult = new StreamResult

(out);            transformer.transform(domSource, xmlResult);        } catch (Exception e) {            System.out.println("保存文件出错!");        }    }

  
--------------------------------------------------------------------------------
本人获取的一份XML保存如下

<?xml version="1.0" encoding="UTF-8" ?> - <rss xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:yweather="http://xml.weather.yahoo.com/ns/rss/1.0"

version="2.0">- <channel>  <title>Yahoo! Weather - Wuhan, CH</title>  

<link>http://us.rd.yahoo.com/dailynews/rss/weather/Wuhan__CH/*http://weather.yahoo.com/forecast/CHXX0138_c.html</link>   <description>Yahoo! Weather for

Wuhan, CH</description>   <language>en-us</language>   <lastBuildDate>Sat, 27 Mar 2010 11:00 pm CST</lastBuildDate>   <ttl>60</ttl>   <yweather:location

city="Wuhan" country="CH" region="" />   <yweather:units distance="km" pressure="mb" speed="km/h" temperature="C" />   <yweather:wind chill="15"

direction="110" speed="6.44" />   <yweather:atmosphere humidity="67" pressure="1015.92" rising="0" visibility="9.99" />   <yweather:astronomy sunrise="6:19

am" sunset="6:38 pm" /> - <image>  <title>Yahoo! Weather</title>   <width>142</width>   <height>18</height>   <link>http://weather.yahoo.com</link>  

<url>http://l.yimg.com/a/i/us/nws/th/main_142b.gif</url>   </image>- <item>  <title>Conditions for Wuhan, CH at 11:00 pm CST</title>  

<geo:lat>30.58</geo:lat>   <geo:long>114.27</geo:long>  

<link>http://us.rd.yahoo.com/dailynews/rss/weather/Wuhan__CH/*http://weather.yahoo.com/forecast/CHXX0138_c.html</link>   <pubDate>Sat, 27 Mar 2010 11:00 pm

CST</pubDate>   <yweather:condition code="33" date="Sat, 27 Mar 2010 11:00 pm CST" temp="15" text="Fair" /> - <description>- <!--[CDATA[ <img

src="http://l.yimg.com/a/i/us/we/52/33.gif" mce_src="http://l.yimg.com/a/i/us/we/52/33.gif"/><br /><b>Current Conditions:</b><br />Fair, 15 C<BR /><BR

/><b>Forecast:</b><BR />Sat - Partly Cloudy. High: 18 Low: 9<br />Sun - Partly Cloudy. High: 20 Low: 12<br /><br /><a

href="http://us.rd.yahoo.com/dailynews/rss/weather/Wuhan__CH/*http://weather.yahoo.com/forecast/CHXX0138_c.html"

mce_href="http://us.rd.yahoo.com/dailynews/rss/weather/Wuhan__CH/*http://weather.yahoo.com/forecast/CHXX0138_c.html">Full Forecast at Yahoo!

Weather</a><BR/><BR/>(provided by <a href="http://www.weather.com" mce_href="http://www.weather.com" >The Weather Channel</a>)<br/>  ]]-->   </description> 

<yweather:forecast code="29" date="27 Mar 2010" day="Sat" high="18" low="9" text="Partly Cloudy" />   <yweather:forecast code="30" date="28 Mar 2010"

day="Sun" high="20" low="12" text="Partly Cloudy" />   <guid isPermaLink="false">CHXX0138_2010_03_27_23_00_CST</guid>   </item>  </channel>  </rss>- <!-- 

api7.weather.sp1.yahoo.com uncompressed/chunked Sat Mar 27 08:43:16 PDT 2010   -->

  
--------------------------------------------------------------------------------
好啦,下面就是解析XML了,您看一下XML文档,如果您了解的话很容易获取其中的信息

/* 获取天气信息 */    public String getWeather(String city) {        String result = null;        try {            Document doc = getWeatherXML

(GetWeatherInfo.cityCode.get(city));            NodeList nodeList = doc.getElementsByTagName("channel");            for (int i = 0; i < nodeList.getLength();

i++) {                Node node = nodeList.item(i);                NodeList nodeList1 = node.getChildNodes();                for (int j = 0; j <

nodeList1.getLength(); j++) {                    Node node1 = nodeList1.item(j);                    if (node1.getNodeName().equalsIgnoreCase("item")) {      

                 NodeList nodeList2 = node1.getChildNodes();                        for (int k = 0; k < nodeList2.getLength(); k++) {                        

   Node node2 = nodeList2.item(k);                            if (node2.getNodeName().equalsIgnoreCase(                                   

"yweather:forecast")) {                                NamedNodeMap nodeMap = node2.getAttributes();                                Node lowNode =

nodeMap.getNamedItem("low");                                Node highNode = nodeMap.getNamedItem("high");                                Node codeNode =

nodeMap.getNamedItem("code");                                String day = "今天";                                if (result == null) {                       

   (www.111cn.net)         result = "";                                } else {                                    day = "n明天";                            

   }                                result = result                                        + day                                        + " "                

                       + dictionaryStrings[Integer                                                .parseInt(codeNode                                         

              .getNodeValue())]                                        + "t最低温度:" + lowNode.getNodeValue()                                        + "℃

t最高温度:" + highNode.getNodeValue()                                        + "℃ ";                            }                        }                 

  }                }            }            saveXML(doc, "C:UsersyguiDesktopWeather.xml");        } catch (Exception e) {            e.printStackTrace();   

    }        return result;    }

  
--------------------------------------------------------------------------------
整个程序的代码如下:

package stwolf.hustbaidu.java.learn.filelist;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import

java.net.URL;import java.net.URLConnection;import java.util.HashMap;import javax.xml.parsers.DocumentBuilder;import

javax.xml.parsers.DocumentBuilderFactory;import javax.xml.transform.Transformer;import javax.xml.transform.TransformerFactory;import

javax.xml.transform.dom.DOMSource;import javax.xml.transform.stream.StreamResult;import org.w3c.dom.Document;import org.w3c.dom.NamedNodeMap;import

org.w3c.dom.Node;import org.w3c.dom.NodeList;class GetWeatherInfo {    public static HashMap<String, String> cityCode = new HashMap<String, String>();   

private final String[] dictionaryStrings = { "龙卷风", "热带风暴", "飓风", "强雷阵雨",            "雷阵雨", "小雨加雪", "雨加冰雹", "雪加冰雹", "冰雨", "毛毛

雨", "冻雨", "阵雨", "阵雨", "小雪",            "零星小雪", "高吹雪", "雪", "冰雹", "雨夹雪", "尘", "雾", "薄雾", "多烟的", "大风", "有风",            "寒

冷", "阴天", "夜间阴天", "白天阴天", "夜间多云", "白天多云", "夜间清亮", "晴朗", "转晴",            "转晴", "雨夹冰雹", "热", "雷阵雨", "雷阵雨", "雷阵雨", "

雷阵雨", "大雪", "阵雪", "大雪",            "多云", "雷", "阵雪", "雷雨" };    public GetWeatherInfo() {        initCitys();    }    /* 初始化城市代号 */   

private void initCitys() {        cityCode.put("北京", "0008");        cityCode.put("天津", "0133");        cityCode.put("武汉", "0138");       

cityCode.put("杭州", "0044");        cityCode.put("合肥 ", "0448");        cityCode.put("上海 ", "0116");        cityCode.put("福州 ", "0031");       

cityCode.put("重庆 ", "0017");        cityCode.put("南昌 ", "0097");        cityCode.put("香港 ", "0049");        cityCode.put("济南 ", "0064");       

cityCode.put("澳门 ", "0512");        cityCode.put("郑州 ", "0165");        cityCode.put("呼和浩特 ", "0249");        cityCode.put("乌鲁木齐 ", "0135");     

  cityCode.put("长沙 ", "0013");        cityCode.put("银川 ", "0259");        cityCode.put("广州 ", "0037");        cityCode.put("拉萨 ", "0080");       

cityCode.put("海口 ", "0502");        cityCode.put("南京 ", "0100");        cityCode.put("成都 ", "0016");        cityCode.put("石家庄 ", "0122");       

cityCode.put("贵阳 ", "0039");        cityCode.put("太原 ", "0129");        cityCode.put("昆明 ", "0076");        cityCode.put("沈阳 ", "0119");       

cityCode.put("西安 ", "0141");        cityCode.put("长春 ", "0010");        cityCode.put("兰州 ", "0079");        cityCode.put("西宁 ", "0236");    }   

private Document getWeatherXML(String cityCode) throws IOException {        URL url = new URL("http://weather.yahooapis.com/forecastrss?p=CHXX"              

 + cityCode + "&u=c");        URLConnection connection = url.openConnection();        Document Doc = stringToElement(connection.getInputStream());       

return Doc;    }    /* 保存获取的天气信息XML文档 */    private void saveXML(Document Doc, String Path) {        TransformerFactory transFactory =

TransformerFactory.newInstance();        Transformer transformer;        try {            transformer = transFactory.newTransformer();            DOMSource

domSource = new DOMSource(Doc);            File file = new File(Path);            FileOutputStream out = new FileOutputStream(file);            StreamResult

xmlResult = new StreamResult(out);            transformer.transform(domSource, xmlResult);        } catch (Exception e) {            System.out.println("保存

文件出错!");        }    }    /* 获取天气信息 */    public String getWeather(String city) {        String result = null;        try {            Document

doc = getWeatherXML(GetWeatherInfo.cityCode.get(city));            NodeList nodeList = doc.getElementsByTagName("channel");            for (int i = 0; i <

nodeList.getLength(); i++) {                Node node = nodeList.item(i);                NodeList nodeList1 = node.getChildNodes();                for (int j

= 0; j < nodeList1.getLength(); j++) {                    Node node1 = nodeList1.item(j);                    if (node1.getNodeName().equalsIgnoreCase

("item")) {                        NodeList nodeList2 = node1.getChildNodes();                        for (int k = 0; k < nodeList2.getLength(); k++) {      

                     Node node2 = nodeList2.item(k);                            if (node2.getNodeName().equalsIgnoreCase(                                   

"yweather:forecast")) {                                NamedNodeMap nodeMap = node2.getAttributes();                                Node lowNode =

nodeMap.getNamedItem("low");                                Node highNode = nodeMap.getNamedItem("high");                                Node codeNode =

nodeMap.getNamedItem("code");                                String day = "今天";                                if (result == null) {                       

            result = "";                                } else {                                    day = "n明天";                                }          

                     result = result                                        + day                                        + " "                               

        + dictionaryStrings[Integer                                                .parseInt(codeNode                                                       

.getNodeValue())]                                        + "t最低温度:" + lowNode.getNodeValue()                                        + "℃ t最高温度:" +

highNode.getNodeValue()                                        + "℃ ";                            }                        }                    }           

    }            }            saveXML(doc, "C:UsersyguiDesktopWeather.xml");        } catch (Exception e) {            e.printStackTrace();        }       

return result;    }    public Document stringToElement(InputStream input) {        try {            DocumentBuilder db = DocumentBuilderFactory.newInstance()

                   .newDocumentBuilder();            Document doc = db.parse(input);            return doc;        } catch (Exception e) {            return

null;        }    }}public class Test {    public static void main(String arg[]) {        GetWeatherInfo info = new GetWeatherInfo();        String weather =

info.getWeather("武汉");        System.out.println(weather);    }}

from:http://www.111cn.net/jsp/Java/39375.htm
 

 ====================

JAVA Webservices 实现天气预报

 

http://www.webxml.com.cn/Webservices/WeatherWebService.asmx

下面就用java把具体的代码写写吧!
这里我采用比较简单的get请求调用,毕竟这也没什么秘密可言,就用最简单的就可以了。
还有,这里很多捕获异常的东西给我去掉了,自己加吧!

 

{   
private static String SERVICES_HOST = "www.webxml.com.cn";
private static String WEATHER_SERVICES_URL = "http://www.webxml.com.cn/WebServices/WeatherWebService.asmx/";
private static String SUPPORT_CITY_URL = WEATHER_SERVICES_URL
+ "getSupportCity?byProvinceName=ALL";
private static String WEATHER_QUERY_URL = WEATHER_SERVICES_URL
+ "getWeatherbyCityName?theCityName=";
private WeatherUtil(){}
public static InputStream getSoapInputStream(String url)
{
InputStream is = null;

URL U = new URL(url);
URLConnection conn = U.openConnection();
conn.setRequestProperty("Host", SERVICES_HOST);
conn.connect();
is = conn.getInputStream();
return is;
}
//取得支持的城市列表
public static ArrayList<String> getSupportCity()
{
ArrayList cityList = null;
Document doc;
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
DocumentBuilder db = dbf.newDocumentBuilder();
InputStream is = getSoapInputStream(SUPPORT_CITY_URL);
doc = db.parse(is);
NodeList nl = doc.getElementsByTagName("string");
int len = nl.getLength();
cityList = new ArrayList<String>(len);
for (int i = 0; i < len; i++)
{
Node n = nl.item(i);
String city = n.getFirstChild().getNodeValue();
cityList.add(city);
}
is.close();
return cityList;
}
//取得城市的天气
public static ArrayList<String> getWeather(String city)
{
ArrayList weatherList = null;
Document doc;
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
DocumentBuilder db = dbf.newDocumentBuilder();
//这里他的编码格式就是这样,我试了几个也没办法。。只好这样混过去了
InputStream is = getSoapInputStream(WEATHER_QUERY_URL
+ new String(city.getBytes("UTF-8"), "GBK"));
doc = db.parse(is);
NodeList nl = doc.getElementsByTagName("string");
int len = nl.getLength();
weatherList = new ArrayList<String>(len);
for (int i = 0; i < len; i++)
{
Node n = nl.item(i);
String weather = n.getFirstChild().getNodeValue();
weatherList.add(weather);
}
is.close();
return weatherList;
}

public static void main(String[] args) throws Exception
{
ArrayList<String> weatherList = WeatherUtil.getWeather("59287");
// ArrayList<String> weatherList = WeatherUtil.getSupportCity();
for (String weather : weatherList)
{
System.out.println(weather);
}
}
}

 

0 0