【问题标题】:Yahoo weather API, randomly returns old data?雅虎天气 API,随机返回旧数据?
【发布时间】:2016-02-15 15:22:34
【问题描述】:

我开始使用雅虎的免费天气 API 来获取我需要的天气数据,但似乎每次我请求城市天气数据时,我都有可能获得更新数据或返回 1 到 8 天的旧数据。

这是我提出请求的简单 URL: Click here to see a sample request

YQL 查询很简单,它请求纽约市的天气数据:

select * from weather.forecast where woeid in (select woeid from geo.places(1) where text="New York")

但每次我刷新那个 URL 时,我可能会得到完全不同的结果。例如,我现在确实刷新了几次(现在是 2015 年 11 月 13 日,格林威治标准时间 22:45 左右),这是我在query.results.channel.item.condition.date 部分得到的一些结果:

"date":"Fri, 13 Nov 2015 4:49 pm EST"
"date":"Thu, 12 Nov 2015 2:13 am EST"
"date":"Wed, 11 Nov 2015 1:49 am EST"
"date":"Fri, 13 Nov 2015 1:49 am EST"

这很复杂,当我每次发出请求时 API 返回随机日期的天气数据时,我应该如何获取这样的当前天气数据?

我在这里做错了什么或遗漏了什么吗?

注意事项:

更新:

  • 我确实遇到过一个案例,它返回了 8 天前的数据!
  • 使用 YQL 的 SORT 函数并不能解决问题,因为排序是在选择请求的记录后应用的。
  • 今天(2015 年 11 月 25 日),我已经尝试了 20 多次刷新,似乎返回的数据总是正确的,看来问题已经解决了。

  • 2015 年 11 月 26 日,雅虎宣布问题已解决:感谢您的反馈。这个问题已被解决。请再次查看该网站。如果您仍然遇到此问题,请在此论坛上发布新想法。

【问题讨论】:

  • 快一个月了,Yahoo 没有任何动作。我下面的解决方案似乎效果很好,我已经测试了 20 多天。该代码是一个完整的 JavaScript 实现。我同意,反复调用它效率不高,但这是我们所拥有的最好的。大多数时候它会在 5 次尝试内返回。偶尔会超过 15 次尝试。
  • @Vijay Jagdale:此问题已由 Yahoo 修复,请注意我在 11 月 26 日添加的更新:2015 年 11 月 26 日 Yahoo 宣布该问题已修复:感谢您的回馈。这个问题已被解决。请再次查看该网站。如果您仍然遇到此问题,请在此论坛上发布新想法。
  • PS:我投了两次票来结束这个问题,但似乎票数不够。我相信这应该在没有接受的答案的情况下关闭,因为问题是雅虎方面的一个错误,已经修复,而不是编程错误。
  • 实际上它只是在几天前才开始表现得更好。但它并不完全固定。如果你在下面运行我的代码,它会告诉你需要多少次往返才能获得正确的数据,而且它似乎仍然有一半的时间返回过时的数据,并且需要第二次。

标签: yql yahoo-api yahoo-weather-api


【解决方案1】:

我有一个解决方法:重复调用 api,直到获得有效结果。这是我用来制作自己的自定义天气小部件的代码:(当您测试代码时,它有时会返回即使在 30 次尝试后也不可用的数据!)

几天前我也tweeted on #YDN,但没有得到任何回复。

var ydnwthr={};
var ydnStaleness=100000; //YDN weather api is f'ed up and returns stale data, so hammer it repeatedly and then test for data staleness
var abortydn=30; //abort after these many calls
var delayBetweencalls=200; //in milliseconds
var ydncounter=0;
var ydnInterval;
var apiquery=escape('select * from weather.forecast where woeid in (select woeid from geo.places(1) where text="lansing, mi")');
var ydnapiurl='https://query.yahooapis.com/v1/public/yql?q='+apiquery+'&format=json&env='+escape("store://datatables.org/alltableswithkeys");
$(function() { 
   function markupWeather(){
     if(ydnStaleness>1.5) $("#weather").html('weather data not available..');
     else{ 
       /****************THIS IS WHERE YOU DO WHATEVER YOU WANT WITH THE "GOOD" ydnwthr OBJECT ***********/
      var wthrMarkup = "<div id='swHead'>" + ydnwthr.title.replace(/Conditions for | e[sd]t/ig,"") +  "<sub style='font-size:6pt;color:silver'>" +ydncounter+"</sub>"+"</div>";
  	  wthrMarkup += "<div id='swBody' title='updated:" + ydnwthr.pubDate + ". click for details'><div id='swBodyBg'></div><div id='swCurrent'>";
  	  wthrMarkup += ydnwthr.condition.text + ", " + ydnwthr.condition.temp +"&deg;</div></div>";
  	  $("#weather").html(wthrMarkup);
  	  $("#swBodyBg").css('background-image', 'url(' + /".*"/.exec(ydnwthr.description) + ')');
  	  for (i=0;i<5;i++){ //get 5 day weather and fit to container - (done without jquery for convenience)
  	   var el = document.createElement("div");
  	   el.innerText = ydnwthr.forecast[i].day.substr(0,2) + ": " + ydnwthr.forecast[i].text + ", " + ydnwthr.forecast[i].high + "/"+ ydnwthr.forecast[i].low;
  	   $("#swBody")[0].appendChild(el);
  	   while(parseInt(window.getComputedStyle(el, null).getPropertyValue('height')) > 42) {
  		   var fontSize = parseFloat(window.getComputedStyle(el, null).getPropertyValue('font-size'));
  		   el.style.fontSize = (fontSize - 1) + 'px';
  		 }
  	   }
     }
   }//end markupWeather
   ydnInterval=setInterval(function(){
     if(ydnStaleness<=2 || ydncounter>=abortydn) {
	   clearInterval(ydnInterval);
	   markupWeather();
	 }
     $.ajax({url:ydnapiurl}).done(function(data){
	   ydnwthr = data.query.results.channel.item;
	   if(ydnwthr.pubDate) ydnStaleness=(new Date()-new Date(ydnwthr.pubDate))/3600000;
	 });
	 ydncounter++;
   },delayBetweencalls);
});
#weather {border:3px ridge silver;border-radius:5px;cursor:pointer;width:180px;font:10pt/28px arial,sans-serif}
  #swHead {background:#bddeff;font-weight:bold;text-align:center;border-bottom:1px solid silver}
  #swBodyBg{position:absolute;background-position:center;background-size:100px 100px;background-repeat:no-repeat;opacity: 0.5;height:100%;width:100%;z-index:-1}
  #swBody{margin:0px 3px;position:relative;}
  #swCurrent{padding:5px;font:bold 1.1em arial; width:100%;text-align:center}
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="weather" 
  onclick="self.open('http://www.wunderground.com/cgi-bin/findweather/getForecast?brand=wxmap&query=42.74461,-84.47283&lat=42.74461&lon=-84.47283&zoom=11&type=terrain&units=english&rad=0&sat=0&svr=0&cams=0&tor=0&wxsn=1&wxsn.mode=tw&wxsn.opa=50&wxsn.bcdgtemp=0&wxsn.rf=0')">
  <i class="fa fa-spinner fa-spin fa-2x" style="margin:40px 65px"></i>
  <div style="margin:30px">getting weather...</div>
  </div>

【讨论】:

  • 在标题行的末尾有一个很小的数字(下标,浅灰色,几乎看不到),它显示了 api 在获得正确数据之前被调用了多少次。如果 YDN 没有修复这个 api,weather.gov 是另一个我可以切换到的优秀 api。 NOAA 也提供历史气候数据。
【解决方案2】:

雅虎开发者在推特上回复说他们正在调查这个问题。您可以在此处跟进并投票(以加快流程):

https://yahoo.uservoice.com/forums/207813/suggestions/10740099

【讨论】:

    【解决方案3】:

    我多年来一直使用 Yahoo Weather API XML 格式,并在最近几周注意到了这个新错误。我尝试将错误报告给https://developer.yahoo.com/weather/support,但找不到 404 页面。如果等于当前日期,我决定解析返回的日期,如果不等于 re-call sub,则继续。这样我总能得到当前的天气,但不幸的是,这是很多不必要的流量/请求,也许 YDN 会意识到并修复。但无法报告我不知道。我知道这不是解决办法,而是创可贴,祝你好运!

    Private Sub btnWeather_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnWeather.Click
    
        If InternetConnection() = False Then
            MsgBox("No internet connection!", vbExclamation, "Oops!")
            Exit Sub
        Else
    
            'MsgBox("Internet connection detected!", vbInformation, "Huray!")
    
            btnWeather.Enabled = False
            lblWorking.Text = "Working ..."
            tbTries.Text = "1"
    
            Try
    
                Dim t As New clsWeather(Format(Me.TxtBoxZIP.Text), "f")
                lblTodaysDate.Text = FormatDateTime(Now.Date, DateFormat.ShortDate)
                tbHigh.Text = t.high & "°"
                lblCity.Text = TxtBoxZIP.Text & " Weather "
                tbLow.Text = t.Low & "°"
                tbDay.Text = t.day
                tbDate.Text = t.date1
                tbCurrenttemp.Text = t.currenttemp & "°"
                tbCurrentCode.Text = t.currentcode
                tbForcastCode.Text = t.ForcastCode
                tbSunrise.Text = t.Sunrise
                tbSunset.Text = t.Sunset
                tbWind.Text = CInt(Val(t.Wind)) & " mph"
                tbHumidity.Text = CInt(Val(t.humidity))
                imgWeather.Image = Image.FromFile(t.GetImage)
                CodeName()
    
    
                If t.currenttemp < 85 And t.currenttemp > 45 Then
    
                    lblFeelsLike.Text = ""
                    tbFeelsLike.Text = ""
    
                End If
    
                If t.currenttemp > 85 Then
    
                    lblFeelsLike.Text = "Heat Index:"
    
                    Dim Temp = t.currenttemp
                    Dim RH = CInt(Val(t.humidity))
    
                    tbFeelsLike.Text = (-42.379 + 2.04901523 * Temp) + (10.14333127 * RH) - (0.22475541 * Temp * RH) - (0.00683783 * Temp * Temp) - (0.05481717 * RH * RH) + (0.00122874 * Temp * Temp * RH) + (0.00085282 * Temp * RH * RH) - (0.00000199 * Temp * Temp * RH * RH)
    
                    Dim num As Decimal = CType(tbFeelsLike.Text, Decimal)
                    Me.tbFeelsLike.Text = String.Format("{0:n0}", num)
                    tbFeelsLike.Text = tbFeelsLike.Text & "°"
    
                End If
    
                If t.currenttemp < 45 Then
    
                    lblFeelsLike.Text = "Wind Chill:"
                    tbFeelsLike.Text = CInt(Val(t.Chill)) & "°"
    
                End If
    
    
            Catch ex As Exception
                MsgBox(ex.Message)
            End Try
    
        End If
    
    
            Dim day As String = DateTime.Now.ToString("dd")
            If day = tbDate.Text = True Then
                tbDate1.Text = tbDate.Text
                btnWeather.Enabled = True
                lblWorking.Text = ""
            Else
                btnWeather_Click(sender, e)
                tbTries.Text = tbTries.Text + 1
            End If
    
    
    End Sub
    

    【讨论】:

    • 虽然这可能会工作很多次(请求直到你得到更新的数据),遗憾的是不能保证它总是工作,如果雅虎长时间发送错误的数据怎么办?在手动刷新中,有时需要超过 10-15 次尝试才能获取正确日期的数据(仍然不是正确的时间)。我不能让我的用户等待几秒钟甚至几分钟来手动刷新。由于问题来自雅虎,我将关闭这个问题并等到他们希望解决它。我已经在他们的支持论坛中报告了这个问题,但似乎没有人在那里检查或关心......
    猜你喜欢
    • 2014-02-01
    • 1970-01-01
    • 2012-08-16
    • 1970-01-01
    • 2013-07-06
    • 1970-01-01
    • 2011-11-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多