ニジカのスカトロ,ニジカトロ. 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.

nico.py 2.5 KiB

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