|
- """
- ニコニコ動画から動画情報を取得するためのヘルパ集
- """
-
- from __future__ import annotations
-
- from typing import TypedDict
-
- import requests
- from bs4 import BeautifulSoup
- from requests.exceptions import Timeout
-
-
- def fetch_video_info (
- video_code: str,
- ) -> VideoInfo | None:
- """
- 動画コードからタイトル、タグ、説明を取得して返す.
-
- Parameters
- ----------
- video_code: str
- 動画コード
-
- Return
- ------
- VideoInfo | None
- 動画情報
- """
-
- bs = _create_bs_from_url (f"https://www.nicovideo.jp/watch/{ video_code }")
- if bs is None:
- return None
-
- try:
- title_tag = bs.find ('title')
- if title_tag is None:
- return None
- title = '-'.join (title_tag.text.split ('-')[:(-1)]).strip ()
-
- tags_str: str = (bs.find ('meta', attrs = { 'name': 'keywords' })
- .get ('content')) # type: ignore
- tags = tags_str.split (',')
-
- description = (bs.find ('meta', attrs = { 'name': 'description' })
- .get ('content')) # type: ignore
- except (AttributeError, TypeError):
- return None
-
- return { 'contentId': video_code,
- 'title': title,
- 'tags': tags,
- 'description': str (description) }
-
-
- def fetch_embed_info (
- url: str,
- ) -> tuple[str, str, str]:
- """
- ニコニコ動画の URL からタイトル、詳細、サムネールを取得して返す.
-
- Parameters
- ----------
- url: str
- 動画 URL
-
- Return
- ------
- tuple[str, str, str]
- タイトル、詳細、サムネールからなるタプル
- """
-
- title = ''
- description = ''
- thumbnail = ''
-
- bs = _create_bs_from_url (url)
- if bs is None:
- return ('', '', '')
-
- tmp = bs.find ('title')
- if tmp is not None:
- title = tmp.text
-
- tmp = bs.find ('meta', attrs = { 'name': 'description' })
- if tmp is not None and hasattr (tmp, 'get'):
- try:
- description = str (tmp.get ('content'))
- except (AttributeError, TypeError):
- pass
-
- tmp = bs.find ('meta', attrs = { 'name': 'thumbnail' })
- if tmp is not None and hasattr (tmp, 'get'):
- try:
- thumbnail = str (tmp.get ('content'))
- except (AttributeError, TypeError):
- pass
-
- return (title, description, thumbnail)
-
-
- def fetch_latest_video (
- tags: list[str],
- ) -> VideoInfo | None:
- """
- ニコニコから指定したタグが含まれる動画を検索し,最新のものを返す.
-
- Parameters
- ----------
- tags: list[str]
- タグ・リスト
-
- Return
- ------
- VideoInfo | None
- 動画情報
- """
-
- tag = ' OR '.join (tags)
- url = f"https://www.nicovideo.jp/tag/{ tag }"
-
- params = { 'sort': 'f',
- 'order': 'd' }
-
- video_info = { }
-
- bs = _create_bs_from_url (url, params)
- if bs is None:
- return None
-
- try:
- video = (bs.find_all ('ul', class_ = 'videoListInner')[1]
- .find ('li', class_ = 'item'))
-
- video_info['contentId'] = video['data-video-id']
- except (AttributeError, IndexError, KeyError, TypeError):
- return None
-
- return fetch_video_info (video_info['contentId'])
-
-
- def _create_bs_from_url (
- url: str,
- params: dict | None = None,
- ) -> BeautifulSoup | None:
- """
- URL から BeautifulSoup オブゼクトを作成する.
-
- Parameters
- ----------
- url: str
- URL
- params: dict | None
- パラメータ
-
- Return
- ------
- BeautifulSoup | None
- BeautifulSoup オブゼクト
- """
-
- if params is None:
- params = { }
-
- try:
- req = requests.get (url, params = params, timeout = 60)
- except Timeout:
- return None
-
- if req.status_code != 200:
- return None
-
- req.encoding = req.apparent_encoding
-
- return BeautifulSoup (req.text, 'html.parser')
-
-
- class VideoInfo (TypedDict):
- """
- 動画情報
- """
-
- contentId: str
- title: str
- tags: list[str]
- description: str
|