YouTube Data API에서 특정 채널의 전송 예정 시간 얻기

28073 단어 PythonYouTubetech

요약


유튜브 데이터 API

  • 에서 ChannelId 기반 애니메이션 보기(비디오Id 보기)

  • 에서 id={先程のvideoId}part='liveStreamingDetails'를 지정하여 items[].liveStreamingDetails.scheduledStartTime 값을 가져옵니다
  • .
    확보scheduledStartTime: 전송 예정 시간(UTC)

    샘플 코드


    from apiclient.discovery import build
    from datetime import datetime, timedelta
    import os
    
    DEVELOPER_KEY = os.environ.get('YOUTUBE_API_KEY', '')
    youtube = build('youtube', 'v3', developerKey=DEVELOPER_KEY)
    
    def youtube_search(channel_id: str, max_results: int = 10) -> list:
      # Search: list で channel_id から検索する
      search_response = youtube.search().list(channelId=channel_id, part='id', order='date').execute()
      return search_response.get('items', [])
    
    def youtube_video_details(video_id: str) -> list:
      # Videos: list で video_id から検索する
      video_response = youtube.videos().list(id=video_id, part='liveStreamingDetails').execute()
      return video_response.get('items', [])
    
    if __name__ == '__main__':
      for item in youtube_search('specific-channel-id'):
        video_id = item['id']['videoId']
        details = youtube_video_detail(video_id)
        if len(details) == 0:
          continue
    
        scheduled_start_time = datetime.strptime(details[0]['liveStreamingDetails']['scheduledStartTime'], '%Y-%m-%dT%H:%M:%SZ')
        scheduled_start_time_jst = scheduled_start_time + timedelta(hours=9)  # 日本時間(JST)にする
    
        print(video_id, scheduled_start_time_jst)
    

    디테일


    사전 준비


    API Key(유튜브 데이터 API 사전 검색)참고 자료
    샘플 코드의 Python 환경은 다음과 같습니다.
    [requires]
    python_version = "3.9"
    
    [packages]
    google-api-python-client = "2.33.0"
    

    채널 비디오 목록 가져오기


    Search:list를 사용하여 특정 채널의 비디오 요약
    def youtube_search(channel_id: str, max_results: int = 10) -> list:
      # Search: list で channel_id から検索する
      search_response = youtube.search().list(channelId=channel_id, part='id', order='date').execute()
      return search_response.get('items', [])
    
    지정order='date'을 통해 최신 애니메이션 순서가 됩니다(전송도 애니메이션 대상으로 처리됨).
    API의 응답은 다음과 같습니다.
    따라서
    {
      "kind": "youtube#searchListResponse",
      "etag": "3LsmrmmY376AFR4PJuk5OkUofT0",
      "nextPageToken": "CAEQAA",
      "regionCode": "JP",
      "pageInfo": {
        "totalResults": 223,
        "resultsPerPage": 1
      },
      "items": [
        {
          "kind": "youtube#searchResult",
          "etag": "x9fp9u9w-o4tJvgo1cvh1zT9QIE",
          "id": {
            "kind": "youtube#video",
            "videoId": "whTWQw7RdTk"
          }
        },
        ...
      ]
    }
    
    의 내용을 순환해서 영상을 꺼냅니다.
      for item in youtube_search('specific-channel-id'):
        video_id = item['id']['videoId']
    

    비디오 세부 정보에서 전송 예정 시간 얻기


    Videos:list를 사용하여 지정 items 을 통해 분배 예정 시간을 얻을 수 있습니다
    def youtube_video_details(video_id: str) -> list:
      # Videos: list で video_id から検索する
      video_response = youtube.videos().list(id=video_id, part='liveStreamingDetails').execute()
      return video_response.get('items', [])
    
    API의 응답은 다음과 같습니다.
    {
      "kind": "youtube#videoListResponse",
      "etag": "-cbm6QZrnDdr18MIaJEQ80xCzq8",
      "items": [
        {
          "kind": "youtube#video",
          "etag": "8xuNa38mAiZKoS_Wiq6eEYDNhqE",
          "id": "whTWQw7RdTk",
          "liveStreamingDetails": {
            "actualStartTime": "2021-12-28T14:30:21Z",
            "actualEndTime": "2021-12-28T15:38:22Z",
            "scheduledStartTime": "2021-12-28T14:30:00Z"
          }
        }
      ],
      "pageInfo": {
        "totalResults": 1,
        "resultsPerPage": 1
      }
    }
    
    ※ 해당 분배가 끝났기 때문에 part='liveStreamingDetails'actualStartTime가 존재합니다.actualEndTime 배포 전/배포 후
    또한 일반 공개 애니메이션의 경우 속성이 존재하지 않습니다scheduledStartTime. 참고(고급 공개는 검증되지 않음)
    애니메이션이 할당됨을 전제로 liveStreamingDetails의 값을 얻어 items[].liveStreamingDetails.scheduledStartTime 대상으로 변환
        details = youtube_video_detail(video_id)
        if len(details) == 0:
          continue
    
        scheduled_start_time = datetime.strptime(details[0]['liveStreamingDetails']['scheduledStartTime'], '%Y-%m-%dT%H:%M:%SZ')
    
    이 시점은 UTC이므로 JST로 변환(실제로 이 시점을 계산 처리하려는 경우에도 시간대를 지정하는 것이 좋다)
        scheduled_start_time_jst = scheduled_start_time + timedelta(hours=9)  # 日本時間(JST)にする
    
    이렇게 얻은 datetime는 분배 예정 시간이 된다

    기타


    Quota 제한 사항 정보


    일반 개발자의 상한은 scheduled_start_time_jst이기 때문에 1시간 1회에 여러 채널을 실행하면 API의 상한에 도달할 수 있다
    자기 관찰의 범위 내에서
  • Search: list -> 100 Queries
  • Videos: list -> 1 Queries
  • 이런 느낌.검색에 비용이 들지만 요청 한 번에 지정할 수 있는 채널Id는 하나뿐입니다.
    따라서 10개의 채널이 있으면 API를 10번 찍고, 한 번 실행하면 1000개의 Queries가 소모된다.
    반면 Videos API는 비용이 거의 들지 않으므로 n+1을 호출해도 문제가 없습니다.

    Quota 절감 정보(API 집중 두드리기 방법)


    하나의 요청에 여러 개의 비디오 Id를 지정할 수 있기 때문에 Quoda를 절약할 수 있습니다
    def youtube_video_details(video_ids: list[str]) -> list:
      video_response = youtube.videos().list(id=','.join(video_ids), part='liveStreamingDetails').execute()
      return video_response.get('items', [])
    
    10000에 비디오 목록을 추가하여 요청 시 video_ids 세그먼트로 전송
    이렇게 하면items에 여러 개의 애니메이션이 포함된 결과
    Search:list에서 여러 채널Id를 지정할 수 없음(2021/12/30 확인)

    Quota 절감 정보(RSS 사용 방법)


    이 기사가 공개된 후 RSS를 사용하는 방법을 가르쳤기 때문에 추가
    유튜브는 RSS도 채널 단위로 제공
    https://www.youtube.com/feeds/videos.xml?channel_id={channelId}
    
    RSS를 획득한 항목은 다음과 같습니다.
    <entry>
      <id>yt:video:whTWQw7RdTk</id>
      <yt:videoId>whTWQw7RdTk</yt:videoId>
      <yt:channelId>UC_T1YqknD5yrpVlupc-ZXzg</yt:channelId>
      <title>【ASMR】お耳のオイルマッサージ⯎大きく触るやついっぱい。近めの吐息とほんのりささやき。睡眠導入、作業用。Oil Ear Massage/Ear Blowing【#イル_フローラ/Vtuber】</title>
      <link rel="alternate" href="https://www.youtube.com/watch?v=whTWQw7RdTk"/>
      <author>
        <name>イル_フローラ</name>
        <uri>https://www.youtube.com/channel/UC_T1YqknD5yrpVlupc-ZXzg</uri>
      </author>
      <published>2021-12-28T15:42:45+00:00</published>
      <updated>2021-12-29T02:51:26+00:00</updated>
      <media:group>
        ...
      </media:group>
    </entry>
    
    RSS의 한 항목에 발송 예정 시간이 포함되지 않기 때문에 Video os:list의 API를 두드려 데이터를 가져와야 합니다

    참고 자료

  • https://coolish.hatenablog.com/entry/2019/01/24/040125

  • 좋은 웹페이지 즐겨찾기