使用Python查询YouTube API播放列表时出现“HTTP错误401:未授权”
我在尝试写一个简单的 Python3 脚本,通过 YouTube 的 API 获取一些播放列表的信息。不过,我总是遇到 401 错误,而当我在浏览器中输入请求字符串或者用 w-get 发请求时,一切都正常。我对 Python 还比较陌生,感觉自己可能漏掉了什么重要的地方。
这是我的脚本。当然,我实际上使用的是一个真实的 API 密钥。
from urllib.request import Request, urlopen
from urllib.parse import urlencode
api_key = "myApiKey"
playlist_id = input('Enter playlist id: ')
output_file = input('Enter name of output file (default is playlist id')
if output_file == '':
output_file = playlist_id
url = 'https://www.googleapis.com/youtube/v3/playlistItems'
params = {'part': 'snippet',
'playlistId': playlist_id,
'key': api_key,
'fields': 'items/snippet(title,description,position,resourceId/videoId),nextPageToken,pageInfo/totalResults',
'maxResults': 50,
'pageToken': '', }
data = urlencode(params)
request = Request(url, data.encode('utf-8'))
response = urlopen(request)
content = response.read()
print(content)
不幸的是,在 response = urlopen(request)
这一行出现了错误。
Traceback (most recent call last):
File "gpd-helper.py", line 35, in <module>
response = urlopen(request)
File "/usr/lib/python3.4/urllib/request.py", line 153, in urlopen
return opener.open(url, data, timeout)
File "/usr/lib/python3.4/urllib/request.py", line 461, in open
response = meth(req, response)
File "/usr/lib/python3.4/urllib/request.py", line 571, in http_response
'http', request, response, code, msg, hdrs)
File "/usr/lib/python3.4/urllib/request.py", line 499, in error
return self._call_chain(*args)
File "/usr/lib/python3.4/urllib/request.py", line 433, in _call_chain
result = func(*args)
File "/usr/lib/python3.4/urllib/request.py", line 579, in http_error_default
raise HTTPError(req.full_url, code, msg, hdrs, fp)
urllib.error.HTTPError: HTTP Error 401: Unauthorized
我查阅了文档,但没有找到任何提示。根据文档,列出公共播放列表不需要除了 API 密钥以外的其他认证。
1 个回答
1
在深入研究了Python和Google的文档后,我找到了我的问题的解决办法。
Python的Request对象在给定数据参数时会自动创建一个POST请求,但是YouTube的API却期望使用GET请求(虽然可以带上POST参数)。
解决办法是,在Python 3.4中,要么给方法参数提供GET参数
request = Request(url, data.encode('utf-8'), method='GET')
要么把URL和经过URL编码的POST数据连接起来
request = Request(url + '?' + data)