mirror of
https://github.com/JefferyHcool/BiliNote.git
synced 2026-09-08 09:06:40 +08:00
- 新增快手下载器,支持快手视频下载 - 添加下载配置页面,可设置各平台Cookies - 优化后端接口,增加获取和更新Cookies的功能 - 前端新增Downloader组件和相关表单组件 - 更新路由配置,增加下载配置相关路由
102 lines
4.9 KiB
Python
102 lines
4.9 KiB
Python
import logging
|
|
import os
|
|
import re
|
|
|
|
import requests
|
|
from dotenv import load_dotenv
|
|
|
|
from app.services.cookie_manager import CookieConfigManager
|
|
from app.utils.logger import get_logger
|
|
KUAISHOU_API_BASE = 'https://www.kuaishou.com/graphql'
|
|
KUAISHOU_URL = "https://www.kuaishou.com/"
|
|
load_dotenv()
|
|
headers = {
|
|
'Accept-Language': 'zh-CN,zh;q=0.9',
|
|
'Cache-Control': 'no-cache',
|
|
'Connection': 'keep-alive',
|
|
# 'Cookie': 'did=web_9e8cfa4403000587b9e7d67233e6b04c; didv=1719811812378; kpf=PC_WEB; clientid=3; kpn=KUAISHOU_VISION',
|
|
'Origin': 'https://www.kuaishou.com',
|
|
'Pragma': 'no-cache',
|
|
'Referer': 'https://www.kuaishou.com/',
|
|
'Sec-Fetch-Dest': 'empty',
|
|
'Sec-Fetch-Mode': 'cors',
|
|
'Sec-Fetch-Site': 'same-origin',
|
|
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36',
|
|
'accept': '*/*',
|
|
'content-type': 'application/json',
|
|
'sec-ch-ua': '"Not/A)Brand";v="8", "Chromium";v="126", "Google Chrome";v="126"',
|
|
'sec-ch-ua-mobile': '?0',
|
|
'sec-ch-ua-platform': '"Windows"',
|
|
# 'Cookie':cookies.strip()
|
|
}
|
|
|
|
logger = get_logger(__name__)
|
|
|
|
cfm=CookieConfigManager()
|
|
class KuaiShou:
|
|
def __init__(self):
|
|
self.header = headers.copy()
|
|
self.cookie = None
|
|
|
|
@staticmethod
|
|
def _extract_kuaishou_link(text):
|
|
|
|
url = re.findall('http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+', text)
|
|
return url[0]
|
|
|
|
def get_photo_id(self, url):
|
|
response = requests.get(url, allow_redirects=True, headers=self.header)
|
|
real_url = response.url
|
|
# 提取short—video/后面的id
|
|
pattern = re.compile(r'short-video/(\w+)')
|
|
match = pattern.search(real_url)
|
|
return match.group().split('/')[1]
|
|
|
|
def get_temp_cookies(self):
|
|
is_exist = cfm.get('kuaishou')
|
|
print(is_exist)
|
|
if is_exist:
|
|
return is_exist
|
|
res = requests.get(url=KUAISHOU_URL, headers=self.header, allow_redirects=True)
|
|
cookie_string = '; '.join([f"{k}={v}" for k, v in res.cookies.get_dict().items()])
|
|
return cookie_string
|
|
|
|
def get_video_details(self, url, photo_id):
|
|
json_data = {
|
|
'operationName': 'visionVideoDetail',
|
|
"variables": {"photoId": photo_id, "page": "detail"},
|
|
"query": "query visionVideoDetail($photoId: String, $type: String, $page: String, $webPageArea: String) {\n visionVideoDetail(photoId: $photoId, type: $type, page: $page, webPageArea: $webPageArea) {\n status\n type\n author {\n id\n name\n following\n headerUrl\n __typename\n }\n photo {\n id\n duration\n caption\n likeCount\n realLikeCount\n coverUrl\n photoUrl\n liked\n timestamp\n expTag\n llsid\n viewCount\n videoRatio\n stereoType\n croppedPhotoUrl\n manifest {\n mediaType\n businessType\n version\n adaptationSet {\n id\n duration\n representation {\n id\n defaultSelect\n backupUrl\n codecs\n url\n height\n width\n avgBitrate\n maxBitrate\n m3u8Slice\n qualityType\n qualityLabel\n frameRate\n featureP2sp\n hidden\n disableAdaptive\n __typename\n }\n __typename\n }\n __typename\n }\n __typename\n }\n tags {\n type\n name\n __typename\n }\n commentLimit {\n canAddComment\n __typename\n }\n llsid\n danmakuSwitch\n __typename\n }\n}\n"
|
|
}
|
|
response = requests.post(url=KUAISHOU_API_BASE, headers=self.header, json=json_data)
|
|
if response.status_code == 200:
|
|
response.raise_for_status()
|
|
|
|
return response.json()
|
|
else:
|
|
return None
|
|
|
|
def run(self, url):
|
|
real_url = self._extract_kuaishou_link(url)
|
|
if not real_url:
|
|
logger.error(f"快手视频 URL 解析失败 {url}")
|
|
|
|
cookies = self.get_temp_cookies()
|
|
if not cookies:
|
|
logger.error(f"快手视频 cookies 解析失败 {url},请考虑设置环境变量 KUAISHOU_COOKIES")
|
|
|
|
self.header['Cookie'] = cookies.strip()
|
|
photo_id = self.get_photo_id(real_url)
|
|
if photo_id is None:
|
|
logger.error(f"快手视频 ID 解析失败 {url}")
|
|
video_details = self.get_video_details(real_url, photo_id)
|
|
print(video_details)
|
|
if video_details is None:
|
|
logger.error(f"快手视频详情解析失败 {url}")
|
|
return video_details['data']
|
|
|
|
|
|
if __name__ == '__main__':
|
|
ks = KuaiShou()
|
|
ks.run(
|
|
'https://v.kuaishou.com/2vBqX74 王宝强携手刘昊然、岳云鹏上演精彩名场面 全程高能 看一遍笑一遍 "唐探1900 "快成长计划 ...更多')
|