diff --git a/py/tests/test_世纪音乐.py b/py/tests/test_世纪音乐.py index 4963f9c..ee5a091 100644 --- a/py/tests/test_世纪音乐.py +++ b/py/tests/test_世纪音乐.py @@ -213,6 +213,24 @@ class TestSJMusicSpider(unittest.TestCase): self.assertEqual(playlist_vod["vod_play_url"], "安静$music:401#晴天$music:402") self.assertEqual(singer_vod["vod_play_url"], "青花瓷$music:501#稻香$music:502") + def test_player_content_maps_music_and_mv_ids(self): + song = self.spider.playerContent("世纪音乐", "music:123", {}) + mv = self.spider.playerContent("世纪音乐", "vplay:456:1080", {}) + self.assertEqual(song["parse"], 0) + self.assertEqual(song["url"], "https://www.4c44.com/data/down.php?ac=music&id=123") + self.assertEqual(mv["url"], "https://www.4c44.com/data/down.php?ac=vplay&id=456&q=1080") + + def test_player_content_returns_empty_url_for_invalid_id(self): + self.assertEqual(self.spider.playerContent("世纪音乐", "bad", {})["url"], "") + + @patch.object(Spider, "fetch") + def test_filters_include_singer_mv_and_playlist_groups(self, mock_fetch): + mock_fetch.return_value = SimpleNamespace(status_code=200, text=HOME_HTML) + filters = self.spider.homeContent(False)["filters"] + self.assertEqual([item["key"] for item in filters["singer"]], ["sex", "area", "char"]) + self.assertEqual([item["key"] for item in filters["mv"]], ["area", "type", "sort"]) + self.assertEqual([item["key"] for item in filters["playlist"]], ["lang", "style"]) + if __name__ == "__main__": unittest.main() diff --git a/py/世纪音乐.py b/py/世纪音乐.py index b603c78..11ae2fc 100644 --- a/py/世纪音乐.py +++ b/py/世纪音乐.py @@ -72,7 +72,70 @@ class Spider(BaseSpider): return text.split(marker, 1)[1].split(".html", 1)[0].split("/", 1)[0] def _build_filters(self): - return {"singer": [], "mv": [], "playlist": []} + return { + "singer": [ + { + "key": "sex", + "name": "性别", + "value": [ + {"n": "女歌手", "v": "girl"}, + {"n": "男歌手", "v": "male"}, + {"n": "乐队组合", "v": "band"}, + ], + }, + { + "key": "area", + "name": "地区", + "value": [ + {"n": "华语", "v": "huayu"}, + {"n": "欧美", "v": "oumei"}, + {"n": "韩国", "v": "hanguo"}, + {"n": "日本", "v": "riben"}, + ], + }, + { + "key": "char", + "name": "字母", + "value": [{"n": "全部", "v": "index"}], + }, + ], + "mv": [ + { + "key": "area", + "name": "地区", + "value": [{"n": "全部地区", "v": "index"}], + }, + { + "key": "type", + "name": "类型", + "value": [{"n": "全部类型", "v": "index"}], + }, + { + "key": "sort", + "name": "排序", + "value": [ + {"n": "最新", "v": "new"}, + {"n": "最热", "v": "hot"}, + {"n": "上升最快", "v": "rise"}, + ], + }, + ], + "playlist": [ + { + "key": "lang", + "name": "语种", + "value": [{"n": "全部语种", "v": "index"}], + }, + { + "key": "style", + "name": "风格", + "value": [ + {"n": "流行", "v": "liuxing"}, + {"n": "摇滚", "v": "yaogun"}, + ], + }, + ], + } def _parse_home_items(self, html): root = self._load_html(html) @@ -125,6 +188,15 @@ class Spider(BaseSpider): return f"vplay:{value}:1080" return "" + def _decode_play_id(self, play_id): + raw = str(play_id or "").strip() + if raw.startswith("music:"): + return "music", raw.split(":", 1)[1], "0" + if raw.startswith("vplay:"): + _, mv_id, quality = raw.split(":", 2) + return "vplay", mv_id, quality + return "", "", "" + def _parse_list_cards(self, html, expected_prefixes): root = self._load_html(html) items = [] @@ -285,3 +357,20 @@ class Spider(BaseSpider): ] } return {"list": []} + + def playerContent(self, flag, id, vipFlags): + kind, value, quality = self._decode_play_id(id) + if kind == "music": + url = f"{self.host}/data/down.php?ac=music&id={value}" + elif kind == "vplay": + url = f"{self.host}/data/down.php?ac=vplay&id={value}&q={quality}" + else: + url = "" + return { + "parse": 0, + "url": url, + "header": { + "User-Agent": self.headers["User-Agent"], + "Referer": self.host + "/", + }, + }