【Python】YouTubeの動画URLから動画IDを取り出す【メモ書き】


# まえがき
　YouTubeの動画URLを取り出す手法についてはいくつもの記事が上がっているが、「共有」ボタンを押したときに生成される`https://youtu.be/`で始まる短縮URLへの対応や、URLクエリパラメータ（例えば時間を指定する`t=15`や短縮URLからの転送を示す`feature=youtu.be`など）を含む場合は考慮されてないものばかりな気がしたのでここにメモとして書いてみる。
　ちなみに、再生開始位置を示すYouTubeのURLクエリパラメータ`t`は、
　`https://youtu.be/r4Mkv-q4NmQ?t=5437`や
　`https://youtu.be/r4Mkv-q4NmQ?t=5437s`のように
　全て秒数で指定するのはもちろん、
　`https://youtu.be/r4Mkv-q4NmQ?t=1h30m37s`のように
　`◯h△m□s`とすると「◯時間△分□秒」から再生開始するURLになるぞ！
　※もちろん、`◯h`を省略して`△m□s`とするのも可。

　尚、この記事内のYouTubeのURLは基本的に私の投稿動画やチャンネルURLになっているぞ！

# ソースコード
Python3系で動作。Python2系には`urllib.parse`モジュールがないっぽい。

```python
import urllib.parse
import re

##############################################################
## URLリストからYouTubeの動画id取り出し
## 通常URLと短縮URLに対応。未対応URLではエラーメッセージ表示
## 引数：URLのリスト
## 戻り値：抽出できた動画idのリスト
##############################################################
def pick_up_vid_list(url_list):
  vid_list = []
  pattern_watch = 'https://www.youtube.com/watch?'
  pattern_short = 'https://youtu.be/'

  for i, url in enumerate(url_list):
    # 通常URLのとき
    if re.match(pattern_watch,url):
      yturl_qs = urllib.parse.urlparse(url).query
      vid = urllib.parse.parse_qs(yturl_qs)['v'][0]
      vid_list.append(vid)

    # 短縮URLのとき
    elif re.match(pattern_short,url):
      # "https://youtu.be/"に続く11文字が動画ID
      vid = url[17:28]
      vid_list.append(vid)

    else:
      print('error:\n  URLは\"https://www.youtube.com/watch?\"か')
      print('  \"https://youtu.be/\"で始まるURLを指定してください。')
      print('  - '+ str(i+1)+ '個目：' + url)
  return vid_list
```

# 簡単な解説

　`https://www.youtube.com/watch?`で始まる通常URLでは、動画IDはURLクエリの`v`のパラメータに該当するので、それを取り出しているぞ！
　`https://youtu.be/`で始まる短縮URLでは、`https://youtu.be/`に続く11文字が必ず動画IDになっているので、それを取り出しているぞ！

　12文字に桁上がりする可能性について不安になって正規表現で探したりとか考えなきゃと思ったけどどうやら大丈夫そう。
→[YouTube の v の値が桁上がりする恐れについて - にぽたん研究所](http://blog.livedoor.jp/nipotan/archives/50588074.html "YouTube の v の値が桁上がりする恐れについて - にぽたん研究所")
あとこの記事によると、`[0-9][a-z][A-Z]`と、`-`と`_`とで動画IDはできているらしい。「[URLで使用可能な文字、使用できない文字](https://www.ipentec.com/document/web-url-invalid-char "URLで使用可能な文字、使用できない文字")」によると、これ以外には使えないらしいから文字種類を増やすことはなく、もし足りなくなったら桁数を増やすんでしょうね・・・。

# 使用例

```python
url_list = [
'https://www.youtube.com/watch?v=k3nPaVj8-3w',
'https://www.youtube.com/watch?v=2k-uF-QPcEM&t=5',
'https://www.youtube.com/watch?v=5_Vy0ZtPo_w',
'https://youtu.be/_t-i0KLiJBk',
'https://youtu.be/tfIvsrRxaXg',
'https://youtu.be/biaC_2Mx7Mw?t=283',
'https://www.youtube.com/',
'https://www.youtube.com/channel/UCDWM7dKT5vLXqSi_YljdlBw']
vid_list = pick_up_vid_list(url_list)

for vid in vid_list:
  print (vid)
```

実行結果：

```
error:
  URLは"https://www.youtube.com/watch?"か
  "https://youtu.be/"で始まるURLを指定してください。
  - 7個目：https://www.youtube.com/
error:
  URLは"https://www.youtube.com/watch?"か
  "https://youtu.be/"で始まるURLを指定してください。
  - 8個目：https://www.youtube.com/channel/UCDWM7dKT5vLXqSi_YljdlBw
k3nPaVj8-3w
2k-uF-QPcEM
5_Vy0ZtPo_w
_t-i0KLiJBk
tfIvsrRxaXg
biaC_2Mx7Mw
```

# あとがき
Pythonの標準メソッドにクエリパラメータを分析できるものがある！すげえ楽！
JavaScriptとかだと`purl.js`とか使わないとできないのに！
あ、まあもちろん自分で実装してもできるけどさ・・・面倒じゃん。

# 参考文献
[Pythonでの正規表現の使い方 - Qiita](https://qiita.com/wanwanland/items/ce272419dde2f95cdabc "Pythonでの正規表現の使い方 - Qiita")
[Pythonの正規表現モジュールreの使い方（match、search、subなど） | note.nkmk.me](https://note.nkmk.me/python-re-match-search-findall-etc/ "Pythonの正規表現モジュールreの使い方（match、search、subなど） | note.nkmk.me")
[PythonでURLのクエリ文字列（パラメータ）を取得・作成・変更 | note.nkmk.me](https://note.nkmk.me/python-urllib-parse-query-string/ "PythonでURLのクエリ文字列（パラメータ）を取得・作成・変更 | note.nkmk.me")