上传文件至「api」

This commit is contained in:
2026-08-13 18:03:25 +02:00
parent b632ff2365
commit d4df4a4949
5 changed files with 2374 additions and 0 deletions
+331
View File
@@ -0,0 +1,331 @@
#coding=utf-8
#!/usr/bin/python
import sys
import json
import urllib.parse
from datetime import date
sys.path.append('..')
from base.spider import Spider
# 全局常量 与JS文件完全对齐
DOUBAN_API = "https://frodo.douban.com/api/v2"
API_KEY = "0ac44ae016490db2204ce0a042db2916"
USER_AGENT = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36 MicroMessenger/7.0.9.501 NetType/WIFI MiniProgramEnv/Windows WindowsWechat"
REFERER = "https://servicewechat.com/wx2f9b06c1de1ccfca/84/page-frame.html"
# 图片防盗链后缀
PIC_SUFFIX = '@Referer=https://api.douban.com/@User-Agent=Mozilla/5.0%20(Windows%20NT%2010.0;%20Win64;%20x64)%20AppleWebKit/537.36%20(KHTML,%20like%20Gecko)%20Chrome/113.0.0.0%20Safari/537.36'
# 今日日期,用于判断是否上映
TODAY = date.today().isoformat()
class Spider(Spider):
def getName(self):
return "豆瓣"
def init(self, extend=""):
print("============{0}============".format(extend))
pass
def isVideoFormat(self, url):
pass
def manualVideoCheck(self):
pass
# 核心:判断影片是否已上映(对齐JS isReleased
def isReleased(self, item):
if item.get("release_date"):
return item["release_date"] <= TODAY
if item.get("date"):
return item["date"] <= TODAY
return True
# 核心:构建标准vod结构 对齐JS buildVod
def buildVod(self, item):
# 1. 解析类型 movie/剧集 tv/剧集
rawType = (item.get("type") or "").strip().lower()
typeName = ""
if "movie" in rawType:
typeName = "电影"
elif "tv" in rawType:
typeName = "剧集"
# 2. 解析年份+地区 card_subtitle格式 2025 / 中国大陆
card_subtitle = item.get("card_subtitle", "")
year = ""
region = ""
import re
match = re.match(r"^(\d{4})\s*\/\s*([^\/]+)", card_subtitle)
if match:
year = match.group(1)
region = match.group(2).strip()
# 3. 评分处理
rating_val = "暂无"
rating = item.get("rating")
if rating and rating.get("value", 0) != 0:
rating_val = str(rating["value"])
# 4. 图片处理
pic_url = ""
pic = item.get("pic", {})
if pic and pic.get("normal"):
pic_url = pic["normal"] + PIC_SUFFIX
return {
"vod_id": str(item.get("id", "")),
"vod_name": item.get("title", ""),
"vod_pic": pic_url,
"vod_remarks": f"{typeName}评分 {rating_val}",
"vod_year": f"{year}{region}" if year else ""
}
def homeContent(self, filter):
result = {}
cateManual = {
"热播剧集": "tv_hot",
"热门电影": "hot_movie",
"热播综艺": "show_hot",
"电影筛选": "movie",
"电视筛选": "tv",
"电影榜单": "rank_list_movie",
"电视榜单": "rank_list_tv"
}
classes = []
for k in cateManual:
classes.append({
'type_name': k,
'type_id': cateManual[k]
})
result['class'] = classes
if filter:
result['filters'] = self.config['filter']
return result
# 首页推荐列表(对齐JS homeVod)
def homeVideoContent(self):
try:
params = {
"apikey": API_KEY,
"has_schedule": True,
"count": 30
}
query = urllib.parse.urlencode(params)
url = f"{DOUBAN_API}/subject_collection/subject_real_time_hotest/items?{query}"
rsp = self.fetch(url, headers=self.header, timeout=4000)
jo = json.loads(rsp.text)
joList = jo.get("subject_collection_items", [])
lists = []
for item in joList:
item_type = item.get("type", "")
if item_type not in ["movie", "tv"]:
continue
# 过滤未上映
if not self.isReleased(item):
continue
vod = self.buildVod(item)
if vod["vod_pic"]:
lists.append(vod)
return {"list": lists}
except Exception as e:
return {"list": []}
# 分类列表(对齐JS category
def categoryContent(self, tid, pg, filter, extend):
result = {
"list": [],
"page": int(pg),
"pagecount": 9999,
"limit": 30,
"total": 999999
}
try:
start = (int(pg) - 1) * 30
path = ""
req_params = {
"apikey": API_KEY,
"has_schedule": True,
"start": start,
"count": 30
}
# 分支逻辑完全对齐JS
if tid == "hot_movie":
path = "/movie/hot_gaia"
req_params["sort"] = extend.get("sort", "recommend")
req_params["area"] = extend.get("area", "全部")
data_key = "items"
elif tid in ["tv_hot", "show_hot"]:
sub_type = extend.get("type", tid)
path = f"/subject_collection/{sub_type}/items"
data_key = "subject_collection_items"
elif tid == "movie":
tags = []
if extend.get("类型"):
tags.append(extend["类型"])
if extend.get("地区"):
tags.append(extend["地区"])
if extend.get("年代"):
tags.append(extend["年代"])
req_params["tags"] = ",".join([t for t in tags if t.strip()])
req_params["sort"] = extend.get("sort", "T")
path = "/movie/recommend"
data_key = "items"
elif tid == "tv":
tags = []
if extend.get("类型"):
tags.append(extend["类型"])
if extend.get("电视剧形式"):
tags.append(extend["电视剧形式"])
if extend.get("综艺形式"):
tags.append(extend["综艺形式"])
if extend.get("地区"):
tags.append(extend["地区"])
if extend.get("年代"):
tags.append(extend["年代"])
if extend.get("平台"):
tags.append(extend["平台"])
req_params["tags"] = ",".join([t for t in tags if t.strip()])
req_params["sort"] = extend.get("sort", "T")
path = "/tv/recommend"
data_key = "items"
elif tid in ["rank_list_movie", "rank_list_tv"]:
# 默认榜单ID对齐JS
default_rank = {
"rank_list_movie": "movie_real_time_hotest",
"rank_list_tv": "tv_real_time_hotest"
}[tid]
rank_id = extend.get("榜单", default_rank)
path = f"/subject_collection/{rank_id}/items"
data_key = "subject_collection_items"
else:
return result
# 拼接请求URL
query_str = urllib.parse.urlencode(req_params)
url = f"{DOUBAN_API}{path}?{query_str}"
rsp = self.fetch(url, headers=self.header, timeout=4000)
jo = json.loads(rsp.text)
jolist = jo.get(data_key, [])
videos = []
for vod_item in jolist:
if not self.isReleased(vod_item):
continue
vod = self.buildVod(vod_item)
if vod["vod_pic"]:
videos.append(vod)
result["list"] = videos
return result
except Exception as e:
return result
# 详情、播放、搜索 对齐JS空实现
def detailContent(self, array):
return []
def searchContent(self, key, quick, pg=1):
return {"list": []}
def playerContent(self, flag, id, vipFlags):
return {}
# 请求头 和JS完全一致
header = {
"Host": "frodo.douban.com",
"Connection": "Keep-Alive",
"Referer": REFERER,
"User-Agent": USER_AGENT
}
def localProxy(self, param):
return [200, "video/MP2T", b"", ""]
# 筛选配置 完全复制JS filters
config = {
"player": {},
"filter": {
"hot_movie": [
{"key": "sort", "name": "排序", "value": [
{"n": "热度", "v": "recommend"},
{"n": "最新", "v": "time"},
{"n": "评分", "v": "rank"}
]},
{"key": "area", "name": "地区", "value": [
{"n": "全部", "v": "全部"},
{"n": "华语", "v": "华语"},
{"n": "欧美", "v": "欧美"},
{"n": "韩国", "v": "韩国"},
{"n": "日本", "v": "日本"}
]}
],
"tv_hot": [
{"key": "type", "name": "分类", "value": [
{"n": "综合", "v": "tv_hot"},
{"n": "国产剧", "v": "tv_domestic"},
{"n": "欧美剧", "v": "tv_american"},
{"n": "日剧", "v": "tv_japanese"},
{"n": "韩剧", "v": "tv_korean"},
{"n": "动画", "v": "tv_animation"}
]}
],
"show_hot": [
{"key": "type", "name": "分类", "value": [
{"n": "综合", "v": "show_hot"},
{"n": "国内", "v": "show_domestic"},
{"n": "国外", "v": "show_foreign"}
]}
],
"movie": [
{"key": "类型", "name": "类型", "value": [
{"n": "全部类型", "v": ""}, {"n": "喜剧", "v": "喜剧"}, {"n": "爱情", "v": "爱情"}, {"n": "动作", "v": "动作"}, {"n": "科幻", "v": "科幻"}, {"n": "动画", "v": "动画"}, {"n": "悬疑", "v": "悬疑"}, {"n": "犯罪", "v": "犯罪"}, {"n": "惊悚", "v": "惊悚"}, {"n": "冒险", "v": "冒险"}, {"n": "音乐", "v": "音乐"}, {"n": "历史", "v": "历史"}, {"n": "奇幻", "v": "奇幻"}, {"n": "恐怖", "v": "恐怖"}, {"n": "战争", "v": "战争"}, {"n": "传记", "v": "传记"}, {"n": "歌舞", "v": "歌舞"}, {"n": "武侠", "v": "武侠"}, {"n": "情色", "v": "情色"}, {"n": "灾难", "v": "灾难"}, {"n": "西部", "v": "西部"}, {"n": "纪录片", "v": "纪录片"}, {"n": "短片", "v": "短片"}
]},
{"key": "地区", "name": "地区", "value": [
{"n": "全部地区", "v": ""}, {"n": "华语", "v": "华语"}, {"n": "欧美", "v": "欧美"}, {"n": "韩国", "v": "韩国"}, {"n": "日本", "v": "日本"}, {"n": "中国大陆", "v": "中国大陆"}, {"n": "美国", "v": "美国"}, {"n": "中国香港", "v": "中国香港"}, {"n": "中国台湾", "v": "中国台湾"}, {"n": "英国", "v": "英国"}, {"n": "法国", "v": "法国"}, {"n": "德国", "v": "德国"}, {"n": "意大利", "v": "意大利"}, {"n": "西班牙", "v": "西班牙"}, {"n": "印度", "v": "印度"}, {"n": "泰国", "v": "泰国"}, {"n": "俄罗斯", "v": "俄罗斯"}, {"n": "加拿大", "v": "加拿大"}, {"n": "澳大利亚", "v": "澳大利亚"}, {"n": "爱尔兰", "v": "爱尔兰"}, {"n": "瑞典", "v": "瑞典"}, {"n": "巴西", "v": "巴西"}, {"n": "丹麦", "v": "丹麦"}
]},
{"key": "sort", "name": "排序", "value": [
{"n": "近期热度", "v": "T"}, {"n": "首映时间", "v": "R"}, {"n": "高分优先", "v": "S"}
]},
{"key": "年代", "name": "年代", "value": [
{"n": "全部年代", "v": ""}, {"n": "2026", "v": "2026"}, {"n": "2025", "v": "2025"}, {"n": "2024", "v": "2024"}, {"n": "2023", "v": "2023"}, {"n": "2022", "v": "2022"}, {"n": "2021", "v": "2021"}, {"n": "2020", "v": "2020"}, {"n": "2019", "v": "2019"}, {"n": "2010年代", "v": "2010年代"}, {"n": "2000年代", "v": "2000年代"}, {"n": "90年代", "v": "90年代"}, {"n": "80年代", "v": "80年代"}, {"n": "70年代", "v": "70年代"}, {"n": "60年代", "v": "60年代"}, {"n": "更早", "v": "更早"}
]}
],
"tv": [
{"key": "类型", "name": "类型", "value": [
{"n": "不限", "v": ""}, {"n": "电视剧", "v": "电视剧"}, {"n": "综艺", "v": "综艺"}
]},
{"key": "电视剧形式", "name": "电视剧形式", "value": [
{"n": "不限", "v": ""}, {"n": "喜剧", "v": "喜剧"}, {"n": "爱情", "v": "爱情"}, {"n": "悬疑", "v": "悬疑"}, {"n": "动画", "v": "动画"}, {"n": "武侠", "v": "武侠"}, {"n": "古装", "v": "古装"}, {"n": "家庭", "v": "家庭"}, {"n": "犯罪", "v": "犯罪"}, {"n": "科幻", "v": "科幻"}, {"n": "恐怖", "v": "恐怖"}, {"n": "历史", "v": "历史"}, {"n": "战争", "v": "战争"}, {"n": "动作", "v": "动作"}, {"n": "冒险", "v": "冒险"}, {"n": "传记", "v": "传记"}, {"n": "剧情", "v": "剧情"}, {"n": "奇幻", "v": "奇幻"}, {"n": "惊悚", "v": "惊悚"}, {"n": "灾难", "v": "灾难"}, {"n": "歌舞", "v": "歌舞"}, {"n": "音乐", "v": "音乐"}
]},
{"key": "综艺形式", "name": "综艺形式", "value": [
{"n": "不限", "v": ""}, {"n": "真人秀", "v": "真人秀"}, {"n": "脱口秀", "v": "脱口秀"}, {"n": "音乐", "v": "音乐"}, {"n": "歌舞", "v": "歌舞"}
]},
{"key": "地区", "name": "地区", "value": [
{"n": "全部地区", "v": ""}, {"n": "华语", "v": "华语"}, {"n": "欧美", "v": "欧美"}, {"n": "国外", "v": "国外"}, {"n": "韩国", "v": "韩国"}, {"n": "日本", "v": "日本"}, {"n": "中国大陆", "v": "中国大陆"}, {"n": "中国香港", "v": "中国香港"}, {"n": "美国", "v": "美国"}, {"n": "英国", "v": "英国"}, {"n": "泰国", "v": "泰国"}, {"n": "中国台湾", "v": "中国台湾"}, {"n": "意大利", "v": "意大利"}, {"n": "法国", "v": "法国"}, {"n": "德国", "v": "德国"}, {"n": "西班牙", "v": "西班牙"}, {"n": "俄罗斯", "v": "俄罗斯"}, {"n": "瑞典", "v": "瑞典"}, {"n": "巴西", "v": "巴西"}, {"n": "丹麦", "v": "丹麦"}, {"n": "印度", "v": "印度"}, {"n": "加拿大", "v": "加拿大"}, {"n": "爱尔兰", "v": "爱尔兰"}, {"n": "澳大利亚", "v": "Australia"}
]},
{"key": "sort", "name": "排序", "value": [
{"n": "近期热度", "v": "T"}, {"n": "首播时间", "v": "R"}, {"n": "高分优先", "v": "S"}
]},
{"key": "年代", "name": "年代", "value": [
{"n": "全部", "v": ""}, {"n": "2026", "v": "2026"}, {"n": "2025", "v": "2025"}, {"n": "2024", "v": "2024"}, {"n": "2023", "v": "2023"}, {"n": "2022", "v": "2022"}, {"n": "2021", "v": "2021"}, {"n": "2020", "v": "2020"}, {"n": "2019", "v": "2019"}, {"n": "2010年代", "v": "2010年代"}, {"n": "2000年代", "v": "2000年代"}, {"n": "90年代", "v": "90年代"}, {"n": "80年代", "v": "80年代"}, {"n": "70年代", "v": "70年代"}, {"n": "60年代", "v": "60年代"}, {"n": "更早", "v": "更早"}
]},
{"key": "平台", "name": "平台", "value": [
{"n": "全部", "v": ""}, {"n": "腾讯视频", "v": "腾讯视频"}, {"n": "爱奇艺", "v": "爱奇艺"}, {"n": "优酷", "v": "优酷"}, {"n": "湖南卫视", "v": "湖南卫视"}, {"n": "Netflix", "v": "Netflix"}, {"n": "HBO", "v": "HBO"}, {"n": "BBC", "v": "BBC"}, {"n": "NHK", "v": "NHK"}, {"n": "CBS", "v": "CBS"}, {"n": "NBC", "v": "NBC"}, {"n": "tvN", "v": "tvN"}
]}
],
"rank_list_movie": [
{"key": "榜单", "name": "榜单", "value": [
{"n": "实时热门电影", "v": "movie_real_time_hotest"},
{"n": "一周口碑电影榜", "v": "movie_weekly_best"},
{"n": "豆瓣电影Top250", "v": "movie_top250"}
]}
],
"rank_list_tv": [
{"key": "榜单", "name": "榜单", "value": [
{"n": "实时热门电视", "v": "tv_real_time_hotest"},
{"n": "华语口碑剧集榜", "v": "tv_chinese_best_weekly"},
{"n": "全球口碑剧集榜", "v": "tv_global_best_weekly"},
{"n": "国内口碑综艺榜", "v": "show_chinese_best_weekly"},
{"n": "国外口碑综艺榜", "v": "show_global_best_weekly"}
]}
]
}
}