feat: add jikanyingshi detail and player

This commit is contained in:
Harold
2026-04-23 19:15:36 +08:00
parent dd7798ff3b
commit 04917fd6df
2 changed files with 82 additions and 0 deletions
+38
View File
@@ -165,6 +165,44 @@ class TestJiKanYingShiSpider(unittest.TestCase):
self.assertEqual(result["list"], [])
self.assertEqual(result["total"], 0)
@patch.object(Spider, "_fetch_api")
def test_detail_content_wraps_single_vod_in_list(self, mock_fetch_api):
mock_fetch_api.return_value = {"data": {"vod_id": "d1", "vod_name": "详情片"}}
result = self.spider.detailContent(["d1"])
self.assertEqual(mock_fetch_api.call_args.args, ("/sk-api/vod/one", {"vodId": "d1"}))
self.assertEqual(result, {"list": [{"vod_id": "d1", "vod_name": "详情片"}]})
@patch.object(Spider, "_fetch_api")
def test_player_content_prefers_skjson_url(self, mock_fetch_api):
mock_fetch_api.return_value = {"data": {"url": "https://media.example/final.m3u8"}}
result = self.spider.playerContent("", "https://wrapped.example/play", "")
self.assertEqual(
mock_fetch_api.call_args.args,
("/sk-api/vod/skjson", {"url": "https://wrapped.example/play", "skjsonindex": 0}),
)
self.assertEqual(result["url"], "https://media.example/final.m3u8")
self.assertEqual(result["jx"], 0)
@patch.object(Spider, "_fetch_api")
def test_player_content_falls_back_to_original_id_and_sets_jx_for_video_sites(self, mock_fetch_api):
mock_fetch_api.side_effect = RuntimeError("parse failed")
result = self.spider.playerContent("", "https://v.qq.com/x/cover/abcd", "")
self.assertEqual(result["url"], "https://v.qq.com/x/cover/abcd")
self.assertEqual(result["jx"], 1)
self.assertEqual(result["parse"], 0)
@patch.object(Spider, "_fetch_api")
def test_detail_content_returns_empty_list_when_api_has_no_data(self, mock_fetch_api):
mock_fetch_api.return_value = {"data": None}
self.assertEqual(self.spider.detailContent(["404"]), {"list": []})
if __name__ == "__main__":
unittest.main()
+44
View File
@@ -209,3 +209,47 @@ class Spider(BaseSpider):
return self._page_result(data.get("data") or [], pg, 10)
except Exception:
return self._page_result([], pg, 10)
def detailContent(self, ids):
vod_id = ids[0] if isinstance(ids, (list, tuple)) else ids
try:
data = self._fetch_api("/sk-api/vod/one", {"vodId": vod_id})
except Exception:
return {"list": []}
vod = data.get("data")
return {"list": [vod]} if isinstance(vod, dict) else {"list": []}
def _player_headers(self):
return {
"User-Agent": (
"Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) "
"AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 "
"Mobile/15E148 Safari/604.1"
)
}
def playerContent(self, flag, id, vipFlags):
try:
data = self._fetch_api("/sk-api/vod/skjson", {"url": id, "skjsonindex": 0})
play_url = str((data.get("data") or {}).get("url") or "")
if play_url.startswith("http"):
return {
"parse": 0,
"jx": 0,
"url": play_url,
"header": self._player_headers(),
}
except Exception:
pass
target = str(id or "")
jx = 1 if any(
domain in target.lower()
for domain in ["iqiyi.com", "qq.com", "youku.com", "mgtv.com", "bilibili.com"]
) else 0
return {
"parse": 0,
"jx": jx,
"url": target,
"header": self._player_headers(),
}