使用Python查询YouTube API播放列表时出现“HTTP错误401:未授权”

1 投票
1 回答
6063 浏览
提问于 2025-04-28 09:35

我在尝试写一个简单的 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)

撰写回答