mirror of
https://github.com/ClovertaTheTrilobita/SanYeCao-Nonebot.git
synced 2026-04-01 22:04:51 +00:00
161 lines
4.9 KiB
Python
161 lines
4.9 KiB
Python
import os
|
|
import pickle
|
|
|
|
import ffmpeg
|
|
import requests
|
|
import hashlib
|
|
import urllib.parse
|
|
from selenium import webdriver
|
|
from selenium.webdriver.chrome.options import Options
|
|
from src.configs.path_config import VIDEO_PATH
|
|
|
|
chrome_options = Options()
|
|
chrome_options.add_argument("--headless")
|
|
|
|
if not os.path.exists('bili.cookie'):
|
|
# 使用Selenium模拟浏览器获取Cookie
|
|
driver = webdriver.Chrome(options=chrome_options)
|
|
driver.get("https://www.bilibili.com")
|
|
# cookies = driver.get_cookies()
|
|
with open('bili.cookie', 'wb') as f:
|
|
pickle.dump(driver.get_cookies(), f)
|
|
driver.quit()
|
|
|
|
cookies = pickle.load(open('bili.cookie', 'rb'))
|
|
|
|
headers = {
|
|
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36",
|
|
"referer": "https://www.bilibili.com/",
|
|
"Cookie": "; ".join([f"{c['name']}={c['value']}" for c in cookies])
|
|
}
|
|
|
|
|
|
|
|
appkey = '1d8b6e7d45233436'
|
|
appsec = '560c52ccd288fed045859ed18bffd973'
|
|
|
|
|
|
def appsign(params, appkey, appsec):
|
|
"""为请求参数进行 APP 签名"""
|
|
params.update({'appkey': appkey})
|
|
params = dict(sorted(params.items())) # 按照 key 重排参数
|
|
query = urllib.parse.urlencode(params) # 序列化参数
|
|
sign = hashlib.md5((query+appsec).encode()).hexdigest() # 计算 api 签名
|
|
params.update({'sign':sign})
|
|
return params
|
|
|
|
|
|
def get_video_info(keyword):
|
|
params = {
|
|
'search_type': 'video'
|
|
}
|
|
|
|
signed_params = appsign(params, appkey, appsec)
|
|
query = urllib.parse.urlencode(signed_params)
|
|
url = f"https://api.bilibili.com/x/web-interface/search/type?keyword={keyword}&"
|
|
|
|
session = requests.session()
|
|
session.get("https://www.bilibili.com/", headers=headers)
|
|
response = session.get(url + query, headers=headers).json()
|
|
# print(response['code'])
|
|
return response
|
|
|
|
def get_video_info_bv(keyword):
|
|
params = {
|
|
'bvid': keyword
|
|
}
|
|
|
|
signed_params = appsign(params, appkey, appsec)
|
|
query = urllib.parse.urlencode(signed_params)
|
|
url = "https://api.bilibili.com/x/web-interface/view?&"
|
|
session = requests.session()
|
|
session.get("https://www.bilibili.com/", headers=headers)
|
|
response = session.get(url + query, headers=headers).json()
|
|
return response
|
|
|
|
def get_video_pages_info(keyword):
|
|
"""
|
|
通过BV号获取视频信息
|
|
|
|
:param keyword:
|
|
|
|
:return:
|
|
len(vid_pages_info_list): 视频集数->int
|
|
vid_pages_info_list: 视频分集信息->dict
|
|
vid_title: 视频标题->str
|
|
vid_author: 视频UP主->str
|
|
vid_pic: 视频封面URL->str
|
|
"""
|
|
response = get_video_info_bv(keyword)
|
|
vid_pages_info_list = response['data']['pages']
|
|
vid_title = response['data']['title']
|
|
vid_author = response['data']['owner']['name']
|
|
vid_pic = response['data']['pic']
|
|
return len(vid_pages_info_list), vid_pages_info_list, vid_title, vid_author, vid_pic
|
|
|
|
def get_video_pages_cid(vid_pages_info_list, num):
|
|
cid = vid_pages_info_list[num - 1]['cid']
|
|
return cid
|
|
|
|
def get_video_file_url(bvid, cid):
|
|
params = {
|
|
'bvid': bvid,
|
|
'cid': cid,
|
|
'qn': '64',
|
|
'platform': 'html5'
|
|
}
|
|
|
|
signed_params = appsign(params, appkey, appsec)
|
|
query = urllib.parse.urlencode(signed_params)
|
|
url = "https://api.bilibili.com/x/player/playurl?&"
|
|
|
|
session = requests.session()
|
|
session.get("https://www.bilibili.com/", headers=headers)
|
|
response = session.get(url + query, headers=headers).json()
|
|
|
|
file_url = response['data']['durl'][0]['url']
|
|
|
|
return file_url
|
|
|
|
def video_download(file_url, cid):
|
|
response = requests.get(file_url, headers=headers)
|
|
# 检查请求是否成功
|
|
if response.status_code == 200:
|
|
# 将视频保存到本地文件
|
|
with open(VIDEO_PATH / f'{cid}.mp4', 'wb') as file:
|
|
for chunk in response.iter_content(chunk_size=1024):
|
|
if chunk:
|
|
file.write(chunk)
|
|
print("视频下载完成")
|
|
else:
|
|
print(f"下载失败,状态码:{response.status_code}")
|
|
|
|
def delete_video(cid):
|
|
# 指定要删除的文件路径
|
|
file_path = VIDEO_PATH / f"{cid}.mp4"
|
|
|
|
# 检查文件是否存在
|
|
if os.path.exists(file_path):
|
|
# 删除文件
|
|
os.remove(file_path)
|
|
print(f"文件 {file_path} 已被删除。")
|
|
else:
|
|
print(f"文件 {file_path} 不存在。")
|
|
|
|
def transcode_video(input_file, output_file):
|
|
try:
|
|
# 转码视频为 H.264 编码
|
|
(
|
|
ffmpeg.input(input_file)
|
|
.output(output_file, c="libx264", crf=23, preset="veryfast")
|
|
.run(capture_stdout=True, capture_stderr=True)
|
|
)
|
|
print(f"视频转码完成,输出文件:{output_file}")
|
|
except ffmpeg.Error as e:
|
|
print(f"转码失败:{e.stderr.decode()}")
|
|
|
|
if __name__ == "__main__":
|
|
print(get_video_info('海南某211台风过后现状111'))
|
|
print(get_video_file_url('BV1p2PDeEENs', '28194047730'))
|
|
|
|
print(get_video_pages_info('BV1p2PDeEENs'))
|