问题
I ran into a problem with Yahoo Weather API because it wasn't giving me any data. After visiting YDN website I've found out that all requests should be updated to OAuth 1 starting from March 15th (but I got working it just today!). It's also said to include Yahoo App key and secret. What the request url should look like now, when I must use my app key and secret?
Before, I got such request string: https://query.yahooapis.com/v1/public/yql?q=SOME_QUERY&format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys&callback=
UPDATE
13 minutes after I originally asked this question API calls with /v1/public/ endpoint are working again. But it's still interesting for me to get an answer to my question.
UPDATE
It's down again :(
回答1:
If you simply replace
http://weather.yahooapis.com/
with
http://xml.weather.yahoo.com/
it should work ;)
回答2:
Current Solution As of Mid-April 2016 - Yahoo is Allowing YQL Requests Without Oauth Again Due to Developer Outrage
You can once again write a query without any authentication like the following:
https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20weather.forecast%20where%20woeid%20in%20(select%20woeid%20from%20geo.places(1)%20where%20text%3D%22nome%2C%20ak%22)&format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys
Previous answers below in case they were of help for anyone. During certain periods of Yahoo's changes they did work.
Below are Older Versions of this Answer for Historical Reasons That May Also Still Work
Updated Answer After Yahoo's Latest Round of Updates - Insecure OAuth Workaround
You will need to create a Yahoo account & then create a web application at https://developer.yahoo.com/apps/create/
You will then need to use an OAuth Library to properly encode your Client ID & Client Secret. Here is an example in JavaScript based off a Yahoo Example Page & a 2008 Blog Article by Paul Donnelly. This generates an encoded URL to use to request a weather feed.
//Fill in your consumer Key & Secret from Yahoo's App & adjust location as needed.
//This Key & Secret combination is invalid & won't work for you
var consumerKey = "dj0yJmk9NkRjbXpjUEhPbjlnJmQ9WVdrOVFUQTFaV2wxTjJrbXnHbz3NQSktJnM9Y29uc3VtZXJzZWNyZXQmeD0wOQ--";
var consumerSecret = "9bea8a9k3934d16365ek7e23e0abo1bba4q5c03c";
var locationToQuery = "90210"; //Can be zip code or anything that works in the query select woeid from geo.places(1) where text=<Your Location>
var makeSignedRequest = function(ck,cs,loc) {
var encodedurl = "https://query.yahooapis.com/v1/yql?q=select%20*%20from%20weather.forecast%20where%20woeid%20in%20(select%20woeid%20from%20geo.places(1)%20where%20text%3D%22"+loc+"%22)&format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys";
var accessor = { consumerSecret: cs, tokenSecret: ""};
var message = { action: encodedurl, method: "GET", parameters: [["oauth_version","1.0"],["oauth_consumer_key",ck]]};
OAuth.setTimestampAndNonce(message);
OAuth.SignatureMethod.sign(message, accessor);
var parameterMap = OAuth.getParameterMap(message);
var baseStr = OAuth.decodeForm(OAuth.SignatureMethod.getBaseString(message));
var theSig = "";
if (parameterMap.parameters) {
for (var item in parameterMap.parameters) {
for (var subitem in parameterMap.parameters[item]) {
if (parameterMap.parameters[item][subitem] == "oauth_signature") {
theSig = parameterMap.parameters[item][1];
break;
}
}
}
}
var paramList = baseStr[2][0].split("&");
paramList.push("oauth_signature="+ encodeURIComponent(theSig));
paramList.sort(function(a,b) {
if (a[0] < b[0]) return -1;
if (a[0] > b[0]) return 1;
if (a[1] < b[1]) return -1;
if (a[1] > b[1]) return 1;
return 0;
});
var locString = "";
for (var x in paramList) {
locString += paramList[x] + "&";
}
var finalStr = baseStr[1][0] + "?" + locString.slice(0,locString.length - 1);
return finalStr;
};
//Use the encodedURL to make your request
var encodedURL = makeSignedRequest(consumerKey, consumerSecret, locationToQuery);
It should be noted never to show your consumer key or consumer secret to the public. You can use your own Yahoo Credentials in this Plunkr: http://plnkr.co/edit/EvLbgs
Original Answer
Unfortunately as of right now, the servers are down to create that app. Ideally, once they're back up you can use server side code to do the oauth part. I'll try to edit this answer when that happens. According to Yahoo the URL will be the same except without the /public part. The big difference will be that you need to send request headers with the URL that authenticate your account.
Here's a temporary fix until then. You can still use a YQL query geo.places with a zip code to get the woeid.
select * from geo.places where text=90210 limit 1
You can then grab your woeid from there & use it in the following url to get an xml feed:
http://weather.yahooapis.com/forecastrss?w=WOEID_GOES_HERE
I've created a Plunker as an example of this temporary fix here: http://plnkr.co/edit/dClPDtnToMhHqvKpfCzj?p=preview
Here's the gist of it though using jQuery:
var zipCode = 90210;
$.ajax({
dataType: "json",
headers: { "Accept": "application/json; odata=verbose" },
url: "https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20geo.places%20where%20text%3D"+zipCode+"%20limit%201&format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys",
beforeSend: function(xhr){xhr.setRequestHeader('Accept', 'application/json; odata=verbose');},
success: function(data){
$.getJSON("https://query.yahooapis.com/v1/public/yql?callback=?", {
q: "select * from xml where url=\"https://weather.yahooapis.com/forecastrss?w="+data.query.results.place.locality1.woeid+"\"",
format: "json"
},function (data) {
var weather = data.query.results.rss.channel;
var html = '<div><span class="temperature">'+weather.item.condition.temp+'<span class="degree">°</span><sup>'+weather.units.temperature+'</sup></span><br><span class="wind-chill">Feels like: '+weather.wind.chill+'<span class="degree">°</span></span></div></a>';
$("#weather").html(html);
});
},
});
回答3:
We finally got our yql weather working again using two-legged authorization using yosdk: (https://github.com/isaacs/authentipede)
And using this script
<?php
include_once("yosdk/lib/Yahoo.inc");
define("API_KEY","your-api-key-here");
define("SHARED_SECRET","your-secret-here");
YahooLogger::setDebug(true);
$twoleg = new YahooApplication (API_KEY, SHARED_SECRET);
$query = 'select * from weather.forecast where woeid in (select woeid from geo.places(1) where text="84054") and u="f"';
print_r ($results);
I found this from this discussion: (How do I get started with oauth for YQL for historical stock data?)
回答4:
Apparently, it is meant to no longer work using Public API. For now on, you will be required to use OAuth through Secret Key
.
来源:https://stackoverflow.com/questions/36186538/making-yahoo-weather-api-request-with-oauth-1