本文共 15339 字,大约阅读时间需要 51 分钟。
java 获得天气预报信息
最近项目中需要增加天气预报功能,网上给的资料有很多缺陷比如1. 有些小网站提供的webservers本身就不稳定不能长期使用。
2. 还有一些网站限制访问次数。
3. 再有就是花钱买服务。
根据以上几点只能放弃使用第三方的webservers,由此我们只能找个信得过的提供天气预报的网站抓取页面信息。
接下来我们以中央气象台为例实现从请求到数据解析的过程。
1. 浏览 发现一个搜索功能
做过网页的人都知道通过表单提交城市名字,那我们去看看具体提交到什么地方呢。
在这个from表单中我们发现了什么?对有action 和 keys 这都知道是什么意思我就不废话了。
最终我们得到一个url : =城市名字
哈哈,这就是我们获得天气预报的关键。
2. 通过程序访问url.
以下是使用HttpClient的例子
HttpClient client = new HttpClient();//实例
String url=";
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="?
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="(<[^>]*>)|( )";
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(""
+ 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="#" xmlns:yweather=""
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="" mce_src=" /><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=""
mce_href=" Forecast at Yahoo!
Weather</a><BR/><BR/>(provided by <a href="" mce_href="" >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) {
() 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(""
+ 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 实现天气预报
下面就用java把具体的代码写写吧!
这里我采用比较简单的get请求调用,毕竟这也没什么秘密可言,就用最简单的就可以了。 还有,这里很多捕获异常的东西给我去掉了,自己加吧!
{
private static String SERVICES_HOST = ""; private static String WEATHER_SERVICES_URL = ""; 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); } } }
转载地址:http://gayy.baihongyu.com/