Java 利用雅虎API 采集天气情况

/ 0评 / 0

    是这样的-为了业务需求,产品要求在某页加上天气信息,且根据日落日出时间来提醒行程时间在日落后的人打开车灯。由于业务都在国外,像国家气象中心就凉了,产品极力推荐使用Yahoo Weather。然后折腾了一整日大概摸清了Yahoo的Weather API。

    Yahoo的公共接口实行YSQL的办法,让天气数据可像SQL一样查询。而目前还存活的表为 :geo.places 和weather.forecast。在这之前还有好多表,但出于一些不为人知的原因,雅虎停用了这些表和非常好用的YSQL Console。比如通过经纬度查询Woeid,就会出现需要Api_key的状况,而雅虎则是更新到Oath2.0验证,让你调用也要通过AK来走,而获取动态token的过程又是请求url的,又是拿码办事的,在实际开发直接拉天气(其实是我不会写Java SSL怎么处理)。在这种大环境下只能通过以下的办法来实现:

//获取woeid和Yahoo Location
	 //第一轮准确获取 所得数据基本正确
	 public YahooWeather getYahooCity(YahooWeather city){
		
		 YahooWeather Yahoocity = new YahooWeather();
		 String baseUrl = "https://query.yahooapis.com/v1/public/yql?q=select woeid,locality1,centroid from geo.places(1) where placetype= \"Town LocalAdmin Prefecture\" and text=\"";
		 String useUrl = baseUrl + city.getCityName() +" "+city.getCountryName()+"\"&format=json";
		 String woeid = null, loaction = null;
		
		 try {
			
			String url = UriUtils.encodeQuery(useUrl, "UTF-8");
			SimpleClientHttpRequestFactory cilentfactory = new SimpleClientHttpRequestFactory();
			StringBuffer endCh = new StringBuffer();
			
			URI uri = URI.create(url);
			ClientHttpRequest req = cilentfactory.createRequest(uri, HttpMethod.GET);
			ClientHttpResponse res = req.execute();
			BufferedReader br = new BufferedReader(new InputStreamReader(res.getBody(),Charset.forName("UTF-8")));
			
			String line = null;
			while( (line = br.readLine()) != null){
				endCh.append(line);
			}
			//解析JSON
			JSONObject jsonObject = (JSONObject) JSON.parseObject(endCh.toString(),new TypeReference<Map<String,Object>>(){}).get("query");
			JSONObject results = (JSONObject) JSON.parseObject(jsonObject.toJSONString(),new TypeReference<Map<String,Object>>(){}).get("results");
			if(results!=null){
				JSONObject place = (JSONObject) JSON.parseObject(results.toJSONString(),new TypeReference<Map<String,Object>>(){}).get("place");
				JSONObject centroid = (JSONObject) JSON.parseObject(place.toJSONString(),new TypeReference<Map<String,Object>>(){}).get("centroid");
				JSONObject locality1 = (JSONObject) JSON.parseObject(place.toJSONString(),new TypeReference<Map<String,Object>>(){}).get("locality1");
			
				System.out.println(locality1);
				if(locality1==null){
					System.out.println("["+city.getCityName()+"--"+city.getCountryName()+"] 在雅虎不可查询,无结果返回");
					woeid = "0";
				}else{
					woeid = (String) locality1.get("woeid");
					loaction = centroid.get("latitude")+","+centroid.get("longitude");
				}
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		 
//		 Yahoocity.setCityId(city.getCityId());
//		 Yahoocity.setCityName(city.getCityName());
//		 Yahoocity.setCountryName(city.getCountryName());
//		 Yahoocity.setCountryId(city.getCountryId());
		 Yahoocity.setLocation(loaction);
		 Yahoocity.setWoeid(Integer.parseInt(woeid));
		 
		 return Yahoocity;
	 } 

    其中也没什么值得注意的地方,而其API因为查询是YSQL的形式出现,多了几个参数:比如placetype。placetype是返回的数据当中的一个key。他写作是placetypeName。而我们普通的城市一般是作为Town出现,当然地级市有Admin的形式,也有State这种,比如日本还有道,县。在上面我为了提高精确度稍微限制了一下,而请求的值也是城市名加国家的办法,除此之外也可以通过经纬度 就是以(api_key,lon,lat)的形式出现在Where语句当中,当前测试可用的网址还有:

https://query.yahooapis.com/v1/public/yql?q=select * from weather.forecast where woeid in (select woeid from geo.places(1) where text="北京 中国") and u='c'&format=json 

https://query.yahooapis.com/v1/public/yql?q=select * from weather.forecast where woeid=2488802 and u='c'&format=json

       以上是通过地名直接获取天气和通过woeid获取天气,是最为常用的两种办法。而Yahoo官方本身所提供的API文档和开发者中心(用处不大)当中好多数据都已经废弃,而且部分URL不可用,也不知道这两个能做到什么时候-


发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注