【问题标题】:YouTube Data Api: breaking a nextPageToken while loop if quota limit is reached?YouTube Data Api:如果达到配额限制,则打破 nextPageToken while 循环?
【发布时间】:2019-12-13 01:23:39
【问题描述】:

我正在使用 Python 3 和 YouTube Data API V3 从 YouTube 视频中获取 cmets。这个特定的视频有大约 280,000 cmets。我正在尝试编写一个 while 循环,该循环将在达到配额限制之前获得尽可能多的 cmets,然后在达到配额限制时中断。

我的循环似乎成功调用下一页令牌并将请求的元数据附加到我的列表中,但是当达到配额时,它不会结束循环,而是注册一个 HttpError,并且不保存任何正确获取的评论数据。

这是我当前的代码:

# Get resources:

def get(resource, **kwargs):
    print(f'Getting {resource} with params {kwargs}')
    kwargs['key'] = API_KEY
    response = requests.get(url=f'{YOUTUBE_BASE_URL}/{resource}',
                            params=remove_empty_kwargs(kwargs))
    print(f'Response: {response.status_code}')
    return response.json()


# Getting ALL comments for a video:

def getComments(video_id):
    comments = []
    res = get('commentThreads', part='id,snippet,replies', maxResults=100, videoId=video_id)

    try:
        nextPageToken = res['nextPageToken']
    except TypeError:
        nextPageToken = None

    while (nextPageToken):
        try:
            res = get('commentThreads', part='id,snippet,replies', maxResults=100, videoId=video_id)

            for i in res['items']:
                comments.append(i)

            nextPageToken = res['nextPageToken']

        except HttpError as error:
            print('An error occurred: %s' % error)
            break

    return comments

test = 'video-id-here'
testComments = getComments(test)

所以,发生的事情似乎正确地循环通过了所有 cmets。但是一段时间后,即循环了数百次后,我收到以下错误:


Getting commentThreads with params {'part': 'id,snippet,replies', 'maxResults': 100, 'videoId': 'real video ID shows here'}
Response: 403

KeyError                                  Traceback (most recent call last)
<ipython-input-39-6582a0d8f122> in <module>
----> 1 testComments = getComments(test)

<ipython-input-29-68952caa30dd> in getComments(video_id)
     12             res = get('commentThreads', part='id,snippet,replies', maxResults=100, videoId=video_id)
     13 
---> 14             for i in res['items']:
     15                 comments.append(i)
     16 

KeyError: 'items'

所以,一段时间后,我首先从 API 获得预期的 403 响应,这表明已达到配额限制。然后它会抛出 'items' 的错误,但是抛出这个错误的原因是因为它没有捕获更多的评论线程,所以没有更多的 'items' 可以附加。

我的预期结果是,当达到配额限制时循环将中断,并在达到配额之前保存它设法获取的评论数据。

我认为这可能与我的“尝试”和“除外”处理有关,但我似乎无法弄清楚。

谢谢!

【问题讨论】:

    标签: python python-3.x youtube-api youtube-data-api


    【解决方案1】:

    最终用这段代码修复了它:

    def getComments(video_id):
        comments = []
        res = get('commentThreads', part='id,snippet,replies', maxResults=100, videoId=video_id)
    
        try:
            nextPageToken = res['nextPageToken']
    
        except KeyError:
            nextPageToken = None
    
        except TypeError:
            nextPageToken = None
    
        while (nextPageToken):
            try:
                res = get('commentThreads', part='id,snippet,replies', maxResults=100, videoId=video_id)
    
                for i in res['items']:
                    comments.append(i)
    
                nextPageToken = res['nextPageToken']
    
            except KeyError:
                break
    
        return comments
    

    KeyError 进行适当的异常处理是最终的解决方案,因为我的 get() 函数返回一个 JSON 对象。

    【讨论】:

      【解决方案2】:

      您正在捕获 HttpError 但它从未发生过,因为当您的限制用完时,API 只会返回 403。

      没有要捕获的 HttpError,因此您尝试读取不存在的值并获取 KeyError。

      最可靠的方法可能是检查状态码。

      res = get('commentThreads', part='id,snippet,replies', maxResults=100, videoId=video_id)
      
      if res.status_code != 200:
          break
      
      for i in res['items']:
          comments.append(i)
      
      nextPageToken = res['nextPageToken']
      

      res.status_code 假设您正在使用请求。

      【讨论】:

      • 这对帮助我找出问题所在非常有帮助,谢谢!我发现由于我的 get() 函数是返回 JSON/字典对象,所以我的主要问题是遇到 KeyError。因此,在 while (nextPageToken) 循环中,我将调用嵌套在正确的 try 和 except 语句中,现在它可以工作了!但是您的回答帮助我更好地思考了发生的事情;干杯。
      猜你喜欢
      • 1970-01-01
      • 2022-01-24
      • 1970-01-01
      • 2021-07-20
      • 2020-10-16
      • 1970-01-01
      • 2020-03-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多