ニジカのスカトロ,ニジカトロ. https://bsky.app/profile/deerjika-bot.bsky.social
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

108 lines
2.6 KiB

  1. """
  2. ニコニコのニジカ動画取得モヂュール
  3. """
  4. from typing import TypedDict, cast
  5. import requests
  6. from bs4 import BeautifulSoup
  7. from requests.exceptions import Timeout
  8. from db.models import Video
  9. KIRIBAN_VIEWS_COUNTS = { *range (100, 1_000, 100),
  10. *range (1_000, 10_000, 1_000),
  11. *range (10_000, 1_000_001, 10_000),
  12. 194, 245, 510, 114_514, 1_940, 2_450, 5_100, 24_500,
  13. 51_000, 2_424 }
  14. class VideoInfo (TypedDict):
  15. contentId: str
  16. title: str
  17. tags: list[str]
  18. description: str
  19. def get_latest_deerjika (
  20. ) -> VideoInfo | None:
  21. tag = '伊地知ニジカ OR ぼざろクリーチャーシリーズ'
  22. url = f"https://www.nicovideo.jp/tag/{ tag }"
  23. params = { 'sort': 'f',
  24. 'order': 'd' }
  25. video_info = { }
  26. bs = get_bs_from_url (url, params)
  27. if bs is None:
  28. return None
  29. try:
  30. video = (bs.find_all ('ul', class_ = 'videoListInner')[1]
  31. .find ('li', class_ = 'item'))
  32. video_info['contentId'] = video['data-video-id']
  33. except Exception:
  34. return None
  35. bs = get_bs_from_url ('https://www.nicovideo.jp/watch/'
  36. + video_info['contentId'])
  37. if bs is None:
  38. return None
  39. try:
  40. title = bs.find ('title')
  41. if title is None:
  42. return None
  43. video_info['title'] = '-'.join (title.text.split ('-')[:(-1)])[:(-1)]
  44. tags: str = bs.find ('meta', attrs = { 'name': 'keywords' }).get ('content') # type: ignore
  45. video_info['tags'] = tags.split (',')
  46. video_info['description'] = bs.find ('meta', attrs = { 'name': 'description' }).get ('content') # type: ignore
  47. except Exception:
  48. return None
  49. return cast (VideoInfo, video_info)
  50. def get_bs_from_url (
  51. url: str,
  52. params: dict = { },
  53. ) -> BeautifulSoup | None:
  54. """
  55. URL から BeautifulSoup インスタンス生成
  56. Parameters
  57. ----------
  58. url: str
  59. 捜査する URL
  60. params: dict
  61. パラメータ
  62. Return
  63. ------
  64. BeautifulSoup | None
  65. BeautifulSoup オブゼクト(失敗したら None)
  66. """
  67. try:
  68. req = requests.get (url, params = params, timeout = 60)
  69. except Timeout:
  70. return None
  71. if req.status_code != 200:
  72. return None
  73. req.encoding = req.apparent_encoding
  74. return BeautifulSoup (req.text, 'html.parser')
  75. def get_kiriban_list (
  76. ) -> list[tuple[int, VideoInfo]]:
  77. kiriban_list: list[tuple[int, VideoInfo]] = []