bilibili.py 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. # SPDX-License-Identifier: AGPL-3.0-or-later
  2. """Bilibili is a Chinese video sharing website.
  3. .. _Bilibili: https://www.bilibili.com
  4. """
  5. import random
  6. import string
  7. from urllib.parse import urlencode
  8. from datetime import datetime, timedelta
  9. from searx import utils
  10. # Engine metadata
  11. about = {
  12. "website": "https://www.bilibili.com",
  13. "wikidata_id": "Q3077586",
  14. "official_api_documentation": None,
  15. "use_official_api": False,
  16. "require_api_key": False,
  17. "results": "JSON",
  18. }
  19. # Engine configuration
  20. paging = True
  21. results_per_page = 20
  22. categories = ["videos"]
  23. # Search URL
  24. base_url = "https://api.bilibili.com/x/web-interface/search/type"
  25. cookie = {
  26. "innersign": "0",
  27. "buvid3": "".join(random.choice(string.hexdigits) for _ in range(16)) + "infoc",
  28. "i-wanna-go-back": "-1",
  29. "b_ut": "7",
  30. "FEED_LIVE_VERSION": "V8",
  31. "header_theme_version": "undefined",
  32. "home_feed_column": "4",
  33. }
  34. def request(query, params):
  35. query_params = {
  36. "__refresh__": "true",
  37. "page": params["pageno"],
  38. "page_size": results_per_page,
  39. "single_column": "0",
  40. "keyword": query,
  41. "search_type": "video",
  42. }
  43. params["url"] = f"{base_url}?{urlencode(query_params)}"
  44. params["cookies"] = cookie
  45. return params
  46. def response(resp):
  47. search_res = resp.json()
  48. results = []
  49. for item in search_res.get("data", {}).get("result", []):
  50. title = utils.html_to_text(item["title"])
  51. url = item["arcurl"]
  52. thumbnail = item["pic"]
  53. description = item["description"]
  54. author = item["author"]
  55. video_id = item["aid"]
  56. unix_date = item["pubdate"]
  57. formatted_date = datetime.fromtimestamp(unix_date)
  58. # the duration only seems to be valid if the video is less than 60 mins
  59. duration = utils.parse_duration_string(item["duration"])
  60. if duration and duration > timedelta(minutes=60):
  61. duration = None
  62. iframe_url = f"https://player.bilibili.com/player.html?aid={video_id}&high_quality=1&autoplay=false&danmaku=0"
  63. results.append(
  64. {
  65. "title": title,
  66. "url": url,
  67. "content": description,
  68. "author": author,
  69. "publishedDate": formatted_date,
  70. "length": duration,
  71. "thumbnail": thumbnail,
  72. "iframe_src": iframe_url,
  73. "template": "videos.html",
  74. }
  75. )
  76. return results