kelovp.
首页 API Java 利用雅虎API 采集天气情况

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

是这样的-为了业务需求,产品要求在某页加上天气信息,且根据日落日出时间来提醒行程时间在日落后的人打开车灯。由于业务都在国外,像国家气象中心就凉了,产品极力推荐使用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){

text
	 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));

text
	 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不可用,也不知道这两个能做到什么时候-

K
kelovp
后端工程师 · 广告投放 / 商业化
八年后端,做广告投放与商业化变现系统,现在带团队折腾商业化中台与 AIGC 内容平台。工作之外写点电子音乐、动漫解析和故事。相信把事情想清楚,才写得明白。