From 713c5d98afb05d52506df04098e267c51cfe7c58 Mon Sep 17 00:00:00 2001 From: Harold <8866033@gmail.com> Date: Sat, 25 Apr 2026 09:01:49 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20add=20AAZ=E9=9F=B3=E4=B9=90=20detail=20?= =?UTF-8?q?parsing?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- py/AAZ音乐.py | 93 ++++++++++++++++++++++++++++++++++++++++ py/tests/test_AAZ音乐.py | 56 ++++++++++++++++++++++++ 2 files changed, 149 insertions(+) diff --git a/py/AAZ音乐.py b/py/AAZ音乐.py index 78c3826..1d21689 100644 --- a/py/AAZ音乐.py +++ b/py/AAZ音乐.py @@ -139,6 +139,61 @@ class Spider(BaseSpider): ) return items + def _decode_vod_id(self, vod_id): + raw = str(vod_id or "").strip() + if ":" not in raw: + return "", "" + prefix, value = raw.split(":", 1) + if prefix == "song": + return prefix, "/m/%s.html" % value + if prefix == "singer": + return prefix, "/s/%s" % value + if prefix == "playlist": + return prefix, "/p/%s" % value + if prefix == "album": + return prefix, "/a/%s" % value + if prefix == "mv": + return prefix, "/v/%s" % value + return "", "" + + def _parse_song_detail(self, html, song_id): + title_match = re.search( + r'

(.*?)]+>", " ", title_match.group(1))) if title_match else song_id + singer_match = re.search(r'', str(html or "")) + album_match = re.search(r'所属专辑:]*>([^<]+)', str(html or "")) + cover_match = re.search(r'", str(html or "")) + content_match = re.search(r' """ +SONG_DETAIL_HTML = """ + + + +

夜曲刷新

+ + 所属专辑:范特西 + +
歌曲时长:03:45
+ + +""" + +FOLDER_DETAIL_HTML = """ + +

周董精选

+
+
经典歌曲合集
+ + +""" + class TestAAZMusicSpider(unittest.TestCase): def setUp(self): @@ -135,6 +160,37 @@ class TestAAZMusicSpider(unittest.TestCase): {"page": 1, "limit": 0, "total": 0, "list": []}, ) + @patch.object(Spider, "fetch") + def test_detail_content_builds_song_metadata_and_single_play_url(self, mock_fetch): + mock_fetch.return_value = SimpleNamespace(status_code=200, text=SONG_DETAIL_HTML) + vod = self.spider.detailContent(["song:2001"])["list"][0] + self.assertEqual(vod["vod_name"], "夜曲") + self.assertEqual(vod["vod_pic"], "https://www.aaz.cx/img/song_detail.jpg") + self.assertEqual(vod["vod_remarks"], "周杰伦 | 范特西 | 03:45") + self.assertEqual(vod["vod_play_from"], "AAZ音乐") + self.assertEqual(vod["vod_play_url"], "播放$song:2001") + + @patch.object(Spider, "fetch") + def test_detail_content_builds_folder_track_list_for_singer_playlist_album_and_mv(self, mock_fetch): + mock_fetch.side_effect = [ + SimpleNamespace(status_code=200, text=FOLDER_DETAIL_HTML), + SimpleNamespace(status_code=200, text=FOLDER_DETAIL_HTML), + SimpleNamespace(status_code=200, text=FOLDER_DETAIL_HTML), + SimpleNamespace(status_code=200, text=FOLDER_DETAIL_HTML), + ] + singer_vod = self.spider.detailContent(["singer:jay"])["list"][0] + playlist_vod = self.spider.detailContent(["playlist:jaybest"])["list"][0] + album_vod = self.spider.detailContent(["album:fantasy"])["list"][0] + mv_vod = self.spider.detailContent(["mv:nocturnemv"])["list"][0] + expected = "安静$song:3001#晴天$song:3002" + self.assertEqual(singer_vod["vod_play_url"], expected) + self.assertEqual(playlist_vod["vod_play_url"], expected) + self.assertEqual(album_vod["vod_play_url"], expected) + self.assertEqual(mv_vod["vod_play_url"], expected) + + def test_detail_content_returns_empty_list_for_invalid_vod_id(self): + self.assertEqual(self.spider.detailContent(["bad"])["list"], []) + if __name__ == "__main__": unittest.main()