feat: add AAZ音乐 playback support

This commit is contained in:
Harold
2026-04-25 09:02:51 +08:00
parent 713c5d98af
commit f9e563d6ad
2 changed files with 51 additions and 0 deletions
+34
View File
@@ -1,4 +1,5 @@
# coding=utf-8
import json
import re
import sys
from urllib.parse import quote, urljoin
@@ -194,6 +195,27 @@ class Spider(BaseSpider):
)
return rows
def _post_play_api(self, song_id):
body = "id=%s&type=music" % quote(str(song_id or ""))
response = self.fetch(
self._build_url("/js/play.php"),
headers={
"User-Agent": self.headers["User-Agent"],
"Referer": self._build_url("/m/%s.html" % song_id),
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
"X-Requested-With": "XMLHttpRequest",
},
data=body,
timeout=10,
verify=False,
)
if getattr(response, "status_code", 0) != 200:
return {}
try:
return json.loads(getattr(response, "text", "") or "{}")
except Exception:
return {}
def homeContent(self, filter):
items = self._parse_song_cards(self._fetch_html(self.category_paths["new"]))
return {"class": list(self.classes), "list": items}
@@ -262,3 +284,15 @@ class Spider(BaseSpider):
}
]
}
def playerContent(self, flag, id, vipFlags):
raw = str(id or "").strip()
if not raw.startswith("song:"):
return {"parse": 0, "url": "", "header": dict(self.headers)}
song_id = raw.split(":", 1)[1]
payload = self._post_play_api(song_id)
return {
"parse": 0,
"url": self._clean_text(payload.get("url")),
"header": dict(self.headers),
}
+17
View File
@@ -97,6 +97,9 @@ FOLDER_DETAIL_HTML = """
</body></html>
"""
PLAY_JSON = '{"url":"https://cdn.example.com/aaz/song2001.mp3","pic":"https://cdn.example.com/cover.jpg"}'
EMPTY_PLAY_JSON = '{"url":""}'
class TestAAZMusicSpider(unittest.TestCase):
def setUp(self):
@@ -191,6 +194,20 @@ class TestAAZMusicSpider(unittest.TestCase):
def test_detail_content_returns_empty_list_for_invalid_vod_id(self):
self.assertEqual(self.spider.detailContent(["bad"])["list"], [])
@patch.object(Spider, "fetch")
def test_player_content_resolves_song_id_to_direct_url(self, mock_fetch):
mock_fetch.return_value = SimpleNamespace(status_code=200, text=PLAY_JSON)
result = self.spider.playerContent("AAZ音乐", "song:2001", {})
self.assertEqual(result["parse"], 0)
self.assertEqual(result["url"], "https://cdn.example.com/aaz/song2001.mp3")
self.assertEqual(result["header"]["Referer"], "https://www.aaz.cx/")
@patch.object(Spider, "fetch")
def test_player_content_returns_empty_url_for_invalid_or_empty_payload(self, mock_fetch):
mock_fetch.return_value = SimpleNamespace(status_code=200, text=EMPTY_PLAY_JSON)
self.assertEqual(self.spider.playerContent("AAZ音乐", "song:2001", {})["url"], "")
self.assertEqual(self.spider.playerContent("AAZ音乐", "bad", {})["url"], "")
if __name__ == "__main__":
unittest.main()