feat: (telegram) inline search songs from bili only get results from music type

This commit is contained in:
草师傅 2025-08-24 21:47:59 +08:00
parent 74e97b8bba
commit 91984f45fa
3 changed files with 68 additions and 8 deletions

View file

@ -127,7 +127,7 @@ async def handle_inline_query(query: InlineQuery):
async with aiohttp.ClientSession() as session:
# 先访问 bilibili.com 获取 cookies
async with session.get('https://bilibili.com', headers={
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 Edg/137.0.0.0"}) as response:
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 Edg/138.0.0.0"}) as response:
pass
# 使用获取的 cookies 请求搜索 API
@ -136,7 +136,7 @@ async def handle_inline_query(query: InlineQuery):
'https://api.bilibili.com/x/web-interface/search/all/v2',
params=params,
headers={
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 Edg/137.0.0.0"
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 Edg/138.0.0.0"
}
) as response:
b23_resp = await response.json()

View file

@ -1,6 +1,8 @@
# 一个暂时性的办法用来存储歌曲信息
import aiohttp
from helpers.wbi import get_signed_params
songs = {
"将军的小曲,三太阳的小曲": "你若三冬 - 阿悠悠",
"全斗焕的小曲,光州跑男的小曲,打成一片的小曲,无限制格斗的小曲,重拳的小曲,光州的小曲": "Shake and Sway",
@ -37,18 +39,21 @@ async def fetch_from_b23_api(song_name):
pass
# 使用获取的 cookies 请求搜索 API
params = {'keyword': song_name}
params = {'keyword': song_name, 'search_type': 'video', 'duration': 1, 'order': 'click', 'tid': 3}
# 过一次 wbi 签名,防止被风控
signed_params = get_signed_params(params)
async with session.get(
'https://api.bilibili.com/x/web-interface/search/all/v2',
params=params,
'https://api.bilibili.com/x/web-interface/wbi/search/type',
params=signed_params,
headers={
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 Edg/137.0.0.0"
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 Edg/137.0.0.0",
"referer": "https://www.bilibili.com/",
}
) as response:
resp = await response.json()
if resp and resp.get('data'):
if resp and resp.get('data').get('result'):
# 假设我们只取第一个视频的结果
videos = next((item for item in resp['data']['result'] if item.get('result_type') == 'video'), None)
videos = next((item for item in resp['data']['result'] if item.get('type') == 'video'), None)
first_result = videos['data'][0]
title = first_result.get('title').replace('<em class="keyword">', '').replace('</em>', '') # 清理标题中的 HTML 标签
link = first_result.get('arcurl')

55
helpers/wbi.py Normal file
View file

@ -0,0 +1,55 @@
from functools import reduce
from hashlib import md5
import urllib.parse
import time
import requests
mixinKeyEncTab = [
46, 47, 18, 2, 53, 8, 23, 32, 15, 50, 10, 31, 58, 3, 45, 35, 27, 43, 5, 49,
33, 9, 42, 19, 29, 28, 14, 39, 12, 38, 41, 13, 37, 48, 7, 16, 24, 55, 40,
61, 26, 17, 0, 1, 60, 51, 30, 4, 22, 25, 54, 21, 56, 59, 6, 63, 57, 62, 11,
36, 20, 34, 44, 52
]
def get_mixin_key(orig: str):
'对 imgKey 和 subKey 进行字符顺序打乱编码'
return reduce(lambda s, i: s + orig[i], mixinKeyEncTab, '')[:32]
def enc_wbi(params: dict, img_key: str, sub_key: str):
'为请求参数进行 wbi 签名'
mixin_key = get_mixin_key(img_key + sub_key)
curr_time = round(time.time())
params['wts'] = curr_time # 添加 wts 字段
params = dict(sorted(params.items())) # 按照 key 重排参数
# 过滤 value 中的 "!'()*" 字符
params = {
k : ''.join(filter(lambda chr: chr not in "!'()*", str(v)))
for k, v
in params.items()
}
query = urllib.parse.urlencode(params) # 序列化参数
wbi_sign = md5((query + mixin_key).encode()).hexdigest() # 计算 w_rid
params['w_rid'] = wbi_sign
return params
def get_wbi_keys() -> tuple[str, str]:
'获取最新的 img_key 和 sub_key'
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 Edg/137.0.0.0',
'Referer': 'https://www.bilibili.com/'
}
resp = requests.get('https://api.bilibili.com/x/web-interface/nav', headers=headers)
resp.raise_for_status()
json_content = resp.json()
img_url: str = json_content['data']['wbi_img']['img_url']
sub_url: str = json_content['data']['wbi_img']['sub_url']
img_key = img_url.rsplit('/', 1)[1].split('.')[0]
sub_key = sub_url.rsplit('/', 1)[1].split('.')[0]
return img_key, sub_key
def get_signed_params(params):
img_key, sub_key = get_wbi_keys()
signed_params = enc_wbi(params=params, img_key=img_key, sub_key=sub_key)
return signed_params