Yahoo BOSS V2 授权问题

8 投票
6 回答
2503 浏览
提问于 2025-04-16 22:06

我在使用Yahoo的认证和授权时遇到了很大的困难。我在我的账户中启用了BOSS,设置了支付方式,现在我想用一些Python代码来进行搜索:

import urllib2
import oauth2 as oauth
import time

OAUTH_CONSUMER_KEY = "blahblahblah"
OAUTH_CONSUMER_SECRET = "blah"

def oauth_request(url, params, method="GET"):
    params['oauth_version'] = "1.0",
    params['oauth_nonce'] = oauth.generate_nonce(),
    params['oauth_timestamp'] = int(time.time())

    consumer = oauth.Consumer(key=OAUTH_CONSUMER_KEY,
                              secret=OAUTH_CONSUMER_SECRET)
    params['oauth_consumer_key'] = consumer.key
    req = oauth.Request(method=method, url=url, parameters=params)
    req.sign_request(oauth.SignatureMethod_HMAC_SHA1(), consumer, None)

    return req


if __name__ == "__main__":
    url = "http://yboss.yahooapis.com/ysearch/web"

    req = oauth_request(url, params={"q": "cats dogs"})
    req_url = req.to_url()
    print req_url
    result = urllib2.urlopen(req_url)

但是我一直收到一个错误信息:urllib2.HTTPError: HTTP Error 401: Unauthorized。我搞不清楚是我的密钥出了问题,还是签名的方法有问题,或者我在签名后对数据做了什么修改,还是其他什么原因。有没有人能给点建议?

6 个回答

4

这里有一段我在使用Yahoo! BOSS时有效的Python代码:

import httplib2
import oauth2
import time

OAUTH_CONSUMER_KEY = "Blah"
OAUTH_CONSUMER_SECRET = "Blah"

if __name__ == "__main__":
    url = "http://yboss.yahooapis.com/ysearch/web?q=cats%20dogs"
    consumer = oauth2.Consumer(key=OAUTH_CONSUMER_KEY,secret=OAUTH_CONSUMER_SECRET)
    params = {
        'oauth_version': '1.0',
        'oauth_nonce': oauth2.generate_nonce(),
        'oauth_timestamp': int(time.time()),
    }

    oauth_request = oauth2.Request(method='GET', url=url, parameters=params)
    oauth_request.sign_request(oauth2.SignatureMethod_HMAC_SHA1(), consumer, None)
    oauth_header=oauth_request.to_header(realm='yahooapis.com')

    # Get search results
    http = httplib2.Http()
    resp, content = http.request(url, 'GET', headers=oauth_header)
    print resp
    print content

我使用了一个认证头来提交OAuth签名。

7

我对你的例子做了一些小改动,让它能够正常运行。具体的代码里有注释说明。

import urllib2
import oauth2 as oauth
import time

OAUTH_CONSUMER_KEY = "blahblahblah"
OAUTH_CONSUMER_SECRET = "blah"

def oauth_request(url, params, method="GET"):
    # Removed trailing commas here - they make a difference.
    params['oauth_version'] = "1.0" #,
    params['oauth_nonce'] = oauth.generate_nonce() #,
    params['oauth_timestamp'] = int(time.time())

    consumer = oauth.Consumer(key=OAUTH_CONSUMER_KEY,
                              secret=OAUTH_CONSUMER_SECRET)
    params['oauth_consumer_key'] = consumer.key
    req = oauth.Request(method=method, url=url, parameters=params)
    req.sign_request(oauth.SignatureMethod_HMAC_SHA1(), consumer, None)

    return req


if __name__ == "__main__":
    url = "http://yboss.yahooapis.com/ysearch/web"

    req = oauth_request(url, params={"q": "cats dogs"})
    # This one is a bit nasty. Apparently the BOSS API does not like
    # "+" in its URLs so you have to replace "%20" manually.
    # Not sure if the API should be expected to accept either.
    # Not sure why to_url does not just return %20 instead...
    # Also, oauth2.Request seems to store parameters as unicode and forget
    # to encode to utf8 prior to percentage encoding them in its to_url
    # method. However, it's handled correctly for generating signatures.
    # to_url fails when query parameters contain non-ASCII characters. To
    # work around, manually utf8 encode the request parameters.
    req['q'] = req['q'].encode('utf8')
    req_url = req.to_url().replace('+', '%20')
    print req_url
    result = urllib2.urlopen(req_url)
1

所以我决定放弃Python,试试Perl,结果一切都很顺利。下面是一个简单的代码示例:

use strict;
use Net::OAuth;
use LWP::UserAgent;

my $CC_KEY = "blahblahblah";
my $CC_SECRET = "blah";

my $url = 'http://yboss.yahooapis.com/ysearch/web';
print make_request($url, {q => "cat dog", format => "xml", count => 5});

sub make_request {
    my ($url, $args) = @_;

    my $request = Net::OAuth->request("request token")
      ->new(
            consumer_key => $CC_KEY,
            consumer_secret => $CC_SECRET,
            request_url => $url,
            request_method => 'GET',
            signature_method => 'HMAC-SHA1',
            timestamp => time,
            nonce => int(rand 10**6),
            callback => 'oob',
            extra_params => $args,
            protocol_version => Net::OAuth::PROTOCOL_VERSION_1_0A,
            );
    $request->sign;

    my $res = LWP::UserAgent->new(env_proxy=>1)->get($request->to_url); 
    return $res->content if $res->is_success;
    die $res->status_line;
}

撰写回答