1. add music parser

This commit is contained in:
QAIU
2024-10-21 19:14:29 +08:00
parent 10eec323dd
commit ff569d339c
21 changed files with 689 additions and 62 deletions

View File

@@ -15,7 +15,10 @@ import org.slf4j.LoggerFactory;
/**
* 解析器抽象类包含promise, HTTP Client, 默认失败方法等;
* 新增网盘解析器需要继承该类.
* 新增网盘解析器需要继承该类. <br>
* <h2>实现类命名规则: </h2>
* <p>{网盘标识}Tool, 网盘标识不超过3个字符, 可以取网盘名称首字母缩写或拼音首字母, <br>
* 音乐类型的解析以M开头, 例如网易云音乐Mne</p>
*/
public abstract class PanBase implements IPanTool {
protected Logger log = LoggerFactory.getLogger(this.getClass());
@@ -55,6 +58,10 @@ public abstract class PanBase implements IPanTool {
this.shareLinkInfo = shareLinkInfo;
}
protected PanBase() {
}
/**
* 失败时生成异常消息
*

View File

@@ -80,6 +80,16 @@ public enum PanDomainTemplate {
"http(s)?://163cn\\.tv/(.+)",
"http://163cn.tv/{shareKey}",
MneTool.class),
// https://c6.y.qq.com/base/fcgi-bin/u?__=xxx
MQQ("QQ音乐",
"https://(.+)\\.y\\.qq\\.com/base/fcgi-bin/u\\?__=(.+)",
"https://c6.y.qq.com/base/fcgi-bin/u?__={shareKey}",
MqqTool.class),
// https://t1.kugou.com/song.html?id=xxx
MKG("酷狗音乐",
"https://(.+)\\.kugou\\.com/song\\.html\\?id=(.+)",
"https://t1.kugou.com/song.html?id={shareKey}",
MkgTool.class),
// https://pan.huang1111.cn/s/xxx
// 通用域名([a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,}
CE("Cloudreve",

View File

@@ -0,0 +1,97 @@
package cn.qaiu.parser.impl;
import cn.qaiu.entity.ShareLinkInfo;
import cn.qaiu.parser.PanBase;
import cn.qaiu.util.URLUtil;
import io.vertx.core.Future;
import io.vertx.core.MultiMap;
import io.vertx.core.json.JsonObject;
import io.vertx.uritemplate.UriTemplate;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* 酷狗音乐分享
*/
public class MkgTool extends PanBase {
public static final String API_URL = "https://m.kugou.com/app/i/getSongInfo.php?cmd=playInfo&hash={hash}";
private static final MultiMap headers = MultiMap.caseInsensitiveMultiMap();
static {
// 设置 User-Agent
headers.set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36 Edg/129.0.0.0");
// 设置 Accept
headers.set("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7");
// 设置 If-Modified-Since
headers.set("If-Modified-Since", "Mon, 21 Oct 2024 08:45:50 GMT");
// 设置 Priority
headers.set("Priority", "u=0, i");
// 设置 Sec-CH-UA
headers.set("Sec-CH-UA", "\"Microsoft Edge\";v=\"129\", \"Not=A?Brand\";v=\"8\", \"Chromium\";v=\"129\"");
// 设置 Sec-CH-UA-Mobile
headers.set("Sec-CH-UA-Mobile", "?0");
// 设置 Sec-CH-UA-Platform
headers.set("Sec-CH-UA-Platform", "\"Windows\"");
// 设置 Sec-Fetch-Dest
headers.set("Sec-Fetch-Dest", "document");
// 设置 Sec-Fetch-Mode
headers.set("Sec-Fetch-Mode", "navigate");
// 设置 Sec-Fetch-Site
headers.set("Sec-Fetch-Site", "none");
// 设置 Sec-Fetch-User
headers.set("Sec-Fetch-User", "?1");
// 设置 Upgrade-Insecure-Requests
headers.set("Upgrade-Insecure-Requests", "1");
};
public MkgTool(ShareLinkInfo shareLinkInfo) {
super(shareLinkInfo);
}
public Future<String> parse() {
String shareUrl = shareLinkInfo.getStandardUrl();
// String shareUrl = "https://t1.kugou.com/song.html?id=2bi8Fe9CSV3";
clientNoRedirects.getAbs(shareUrl).send().onSuccess(res -> {
String locationURL = res.headers().get("Location");
client.getAbs(locationURL).putHeaders(headers).send().onSuccess(res2->{
String body = res2.bodyAsString();
// 正则表达式匹配 hash 字段
String regex = "\"hash\"\s*:\s*\"([A-F0-9]+)\"";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(body);
// 查找并输出 hash 字段的值
if (matcher.find()) {
String hashValue = matcher.group(1); // 获取第一个捕获组
System.out.println(hashValue);
client.getAbs(UriTemplate.of(API_URL)).setTemplateParam("hash", hashValue).send().onSuccess(res3 -> {
JsonObject jsonObject = asJson(res3);
System.out.println(jsonObject.encodePrettily());
if (jsonObject.containsKey("url")) {
promise.complete(jsonObject.getString("url"));
} else {
fail("下载链接不存在");
}
}).onFailure(handleFail(API_URL.replace("{hash}", hashValue)));
} else {
fail("歌曲hash匹配失败, 可能分享已失效");
}
}).onFailure(handleFail(locationURL));
}).onFailure(handleFail(shareUrl));
return promise.future();
}
}

View File

@@ -0,0 +1,62 @@
package cn.qaiu.parser.impl;
import cn.qaiu.entity.ShareLinkInfo;
import cn.qaiu.parser.PanBase;
import cn.qaiu.util.JsExecUtils;
import io.vertx.core.Future;
import io.vertx.uritemplate.UriTemplate;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* 酷我音乐分享
* <a href="https://kuwo.cn/play_detail/395500809">分享示例</a>
*/
public class MkwTool extends PanBase {
public static final String API_URL = "https://www.kuwo.cn/api/v1/www/music/playUrl?mid={mid}&type=music&httpsStatus=1&reqId=&plat=web_www&from=";
public MkwTool(ShareLinkInfo shareLinkInfo) {
super(shareLinkInfo);
}
public Future<String> parse() {
// String shareUrl = shareLinkInfo.getStandardUrl();
String shareUrl = "https://kuwo.cn/play_detail/395500809";
clientSession.getAbs(shareUrl).send().onSuccess(result -> {
String cookie = result.headers().get("set-cookie");
if (!cookie.isEmpty()) {
String regex = "([A-Za-z0-9_]+)=([A-Za-z0-9]+)";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(cookie);
if (matcher.find()) {
System.out.println(matcher.group(1));
System.out.println(matcher.group(2));
var key = matcher.group(1);
var token = matcher.group(2);
String sign = JsExecUtils.getKwSign(token, key);
System.out.println(sign);
clientSession.getAbs(UriTemplate.of(API_URL)).setQueryParam("mid", "395500809")
.putHeader("Secret", sign).putHeader("Cookie", key + "=" + token).send().onSuccess(res -> {
System.out.println(res.bodyAsString());
});
}
}
});
return promise.future();
}
MkwTool() {
}
public static void main(String[] args) {
new MkwTool().parse();
}
}

View File

@@ -0,0 +1,25 @@
package cn.qaiu.parser.impl;
import cn.qaiu.entity.ShareLinkInfo;
import cn.qaiu.parser.PanBase;
import io.vertx.core.Future;
import io.vertx.uritemplate.UriTemplate;
/**
* 咪咕音乐分享
*/
public class MmgTool extends PanBase {
public static final String API_URL = "";
public MmgTool(ShareLinkInfo shareLinkInfo) {
super(shareLinkInfo);
}
public Future<String> parse() {
String shareUrl = shareLinkInfo.getStandardUrl();
return promise.future();
}
}

View File

@@ -2,12 +2,14 @@ package cn.qaiu.parser.impl;
import cn.qaiu.entity.ShareLinkInfo;
import cn.qaiu.parser.PanBase;
import cn.qaiu.util.URLUtil;
import io.vertx.core.Future;
import io.vertx.uritemplate.UriTemplate;
/**
* 网易云音乐, 单歌曲直链解析
* <a href="http://163cn.tv/ykLZJJT">示例分享</a>
* <a href="http://163cn.tv/ykLZJJT">示例分享1</a>
* <a href="https://music.163.com/#/song?id=472194327">示例分享2</a>
*/
public class MneTool extends PanBase {
@@ -23,8 +25,7 @@ public class MneTool extends PanBase {
String shareUrl = shareLinkInfo.getStandardUrl();
clientNoRedirects.getAbs(shareUrl).send().onSuccess(res -> {
String locationURL = res.headers().get("Location");
String substring = locationURL.substring(locationURL.indexOf("id="));
String id = substring.substring("id=".length(), substring.indexOf('&'));
String id = URLUtil.from(locationURL).getParam("id");
clientNoRedirects.getAbs(UriTemplate.of(API_URL)).setTemplateParam("id", id).send()
.onSuccess(res2 -> {
promise.complete(res2.headers().get("Location"));

View File

@@ -0,0 +1,65 @@
package cn.qaiu.parser.impl;
import cn.qaiu.entity.ShareLinkInfo;
import cn.qaiu.parser.PanBase;
import cn.qaiu.util.URLUtil;
import io.vertx.core.Future;
import io.vertx.core.json.JsonObject;
import io.vertx.uritemplate.UriTemplate;
/**
*
* QQ音乐分享解析
* <a href="https://c6.y.qq.com/base/fcgi-bin/u?__=w3lqEpOHACLO">分享示例</a>
* <a href="https://y.qq.com/n/ryqq/songDetail/000XjcLg0fbRjv?songtype=0">详情页</a>
*/
public class MqqTool extends PanBase {
public static final String API_URL = "https://u.y.qq.com/cgi-bin/musicu" +
".fcg?-=getplaysongvkey2682247447678878&g_tk=5381&loginUin=956581739&hostUin=0&format=json&inCharset=utf8" +
"&outCharset=utf-8&notice=0&platform=yqq.json&needNewCode=0&data=%7B%22req_0%22%3A%7B%22module%22%3A" +
"%22vkey.GetVkeyServer%22%2C%22method%22%3A%22CgiGetVkey%22%2C%22param%22%3A%7B%22guid%22%3A%222796982635" +
"%22%2C%22songmid%22%3A%5B%22{songmid}%22%5D%2C%22songtype%22%3A%5B1%5D%2C%22uin%22%3A%22956581739%22" +
"%2C%22loginflag%22%3A1%2C%22platform%22%3A%2220%22%7D%7D%2C%22comm%22%3A%7B%22uin%22%3A956581739%2C" +
"%22format%22%3A%22json%22%2C%22ct%22%3A24%2C%22cv%22%3A0%7D%7D";
public MqqTool(ShareLinkInfo shareLinkInfo) {
super(shareLinkInfo);
}
public Future<String> parse() {
String shareUrl = shareLinkInfo.getStandardUrl();
// https://c6.y.qq.com/base/fcgi-bin/u?__=uXXtsB
// String shareUrl = "https://c6.y.qq.com/base/fcgi-bin/u?__=k8gafY6HAQ5Y";
clientNoRedirects.getAbs(shareUrl).send().onSuccess(res -> {
String locationURL = res.headers().get("Location");
String id = URLUtil.from(locationURL).getParam("songmid");
clientNoRedirects.getAbs(UriTemplate.of(API_URL)).setTemplateParam("songmid", id).send().onSuccess(res2 -> {
JsonObject jsonObject = asJson(res2);
System.out.println(jsonObject.encodePrettily());
try {
JsonObject data = jsonObject.getJsonObject("req_0").getJsonObject("data");
String path = data.getJsonArray("midurlinfo").getJsonObject(0).getString("purl");
if (path.isEmpty()) {
fail("暂不支持VIP音乐");
return;
}
String downURL = data.getJsonArray("sip").getString(0)
.replace("http://", "https://") + path;
System.out.println(downURL);
promise.complete(downURL);
} catch (Exception e) {
fail("获取失败");
}
}).onFailure(handleFail(API_URL.replace("{id}", id)));
}).onFailure(handleFail(shareUrl));
return promise.future();
}
public static void main(String[] args) {
new MqqTool(ShareLinkInfo.newBuilder().build()).parse();
}
}

View File

@@ -329,4 +329,73 @@ public class AESUtils {
return _0x53928f + "-" + _0x430930 + "-" + _0x49ec94;
}
public static String encrypt(String str, String pwd) {
if (pwd == null || pwd.length() <= 0) {
throw new IllegalArgumentException("Please enter a password with which to encrypt the message.");
}
// 生成 prand 值
StringBuilder prand = new StringBuilder();
for (int i = 0; i < pwd.length(); i++) {
prand.append((int) pwd.charAt(i));
}
// 计算 sPos, mult, incr, modu
int sPos = prand.length() / 5;
long mult = Long.parseLong(prand.substring(sPos, sPos + 1) +
prand.substring(sPos * 2, sPos * 2 + 1) +
prand.substring(sPos * 3, sPos * 3 + 1) +
prand.substring(sPos * 4, sPos * 4 + 1) +
prand.substring(sPos * 5, sPos * 5 + 1));
int incr = (int) Math.ceil(pwd.length() / 2.0);
long modu = (long) Math.pow(2, 31) - 1;
if (mult < 2) {
throw new IllegalArgumentException("Algorithm cannot find a suitable hash. Please choose a different password.");
}
// 生成 salt 并加到 prand 上
long salt = Math.round(Math.random() * 1000000000) % 100000000;
prand.append(salt);
// 使用 BigInteger 处理超过 Long 范围的 prand 值
BigInteger prandValue = new BigInteger(prand.toString());
while (prandValue.toString().length() > 10) {
prandValue = prandValue.divide(BigInteger.TEN).add(prandValue.remainder(BigInteger.TEN));
}
// 将 prand 转换为 long 进行后续处理
prandValue = prandValue.multiply(BigInteger.valueOf(mult)).add(BigInteger.valueOf(incr)).mod(BigInteger.valueOf(modu));
// 加密过程
StringBuilder encStr = new StringBuilder();
for (int i = 0; i < str.length(); i++) {
// 将字符和异或的结果强制转换为 int
int encChr = (int) (str.charAt(i) ^ (int) ((prandValue.doubleValue() / modu) * 255));
String hexStr = Integer.toHexString(encChr);
if (hexStr.length() < 2) {
encStr.append("0");
}
encStr.append(hexStr);
prandValue = prandValue.multiply(BigInteger.valueOf(mult)).add(BigInteger.valueOf(incr)).mod(BigInteger.valueOf(modu));
}
// 将 salt 转换为 16 进制并追加到加密结果
String saltHex = Long.toHexString(salt);
while (saltHex.length() < 8) {
saltHex = "0" + saltHex;
}
encStr.append(saltHex);
return encStr.toString();
}
public static void main(String[] args) {
// 示例
String encrypted = encrypt("HelloWorld", "password123");
System.out.println("Encrypted String: " + encrypted);
}
}

View File

@@ -149,4 +149,41 @@ public interface JsContent {
""";
String kwSignString = """
function encrypt(str, pwd) {
if (pwd == null || pwd.length <= 0) {
return null;
}
var prand = "";
for (var i = 0; i < pwd.length; i++) {
prand += pwd.charCodeAt(i).toString();
}
var sPos = Math.floor(prand.length / 5);
var mult = parseInt(prand.charAt(sPos) + prand.charAt(sPos * 2) + prand.charAt(sPos * 3) + prand.charAt(sPos * 4) + prand.charAt(sPos * 5));
var incr = Math.ceil(pwd.length / 2);
var modu = Math.pow(2, 31) - 1;
if (mult < 2) {
return null;
}
var salt = Math.round(Math.random() * 1000000000) % 100000000;
prand += salt;
while (prand.length > 10) {
prand = (parseInt(prand.substring(0, 10)) + parseInt(prand.substring(10, prand.length))).toString();
}
prand = (mult * prand + incr) % modu;
var enc_chr = "";
var enc_str = "";
for (var i = 0; i < str.length; i++) {
enc_chr = parseInt(str.charCodeAt(i) ^ Math.floor((prand / modu) * 255));
if (enc_chr < 16) {
enc_str += "0" + enc_chr.toString(16);
} else enc_str += enc_chr.toString(16);
prand = (mult * prand + incr) % modu;
}
salt = salt.toString(16);
while (salt.length < 8) salt = "0" + salt;
enc_str += salt;
return enc_str;
}
""";
}

View File

@@ -8,6 +8,8 @@ import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import static cn.qaiu.util.AESUtils.encrypt;
/**
* 执行Js脚本
*
@@ -57,4 +59,40 @@ public class JsExecUtils {
}
/**
* 调用执行蓝奏云js文件
*/
public static Object executeOtherJs(String jsText, String funName, Object ... args) throws ScriptException,
NoSuchMethodException {
ScriptEngineManager engineManager = new ScriptEngineManager();
ScriptEngine engine = engineManager.getEngineByName("JavaScript"); // 得到脚本引擎
engine.eval(jsText);
Invocable inv = (Invocable) engine;
//调用js中的函数
if (StringUtils.isNotEmpty(funName)) {
return inv.invokeFunction(funName, args);
}
throw new ScriptException("funName is null");
}
public static String getKwSign(String s, String pwd) {
try {
return executeOtherJs(JsContent.kwSignString, "encrypt", s, pwd).toString();
} catch (ScriptException | NoSuchMethodException e) {
throw new RuntimeException(e);
}
}
public static void main(String[] args) {
//encrypt("ZYcEEs2JdncXG8zAaytJiXxmbyhH2wxb", "Hm_Iuvt_cdb524f42f23cer9b268564v7y735ewrq2324")
//'7909e8e754545a61ba4bc3c90c82cb6c69b6859d5ea2e46a6bf913d1b4f11dee011dced1'
// 1e3170f1cc1ca75172409e443b89261ec777e190ebc595b458b8e114a912a9544d2b467323f8ca011b2ed0
// 93a44ef48949d950c91303c84d36
// 95dea502a45fb153f68d8da0bf8e4a095a001e396f60837e9c1b58a48969eb77038234d2
// 93c3750f6ccf9d11b5c304b32495
System.out.println(getKwSign("Hm_lvt_cdb524f42f0ce19b169a8071123a4797", "1729503755"));
System.out.println(getKwSign("HelloWorld", "password123"));
}
}

View File

@@ -0,0 +1,40 @@
package cn.qaiu.util;
import java.net.URL;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Map;
public class URLUtil {
private Map<String, String> queryParams = new HashMap<>();
// 构造函数传入URL并解析参数
private URLUtil(String url) {
try {
URL parsedUrl = new URL(url);
String query = parsedUrl.getQuery();
if (query != null) {
String[] pairs = query.split("&");
for (String pair : pairs) {
String[] keyValue = pair.split("=");
String key = URLDecoder.decode(keyValue[0], "UTF-8");
String value = keyValue.length > 1 ? URLDecoder.decode(keyValue[1], "UTF-8") : "";
queryParams.put(key, value);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
// 静态方法用于创建UrlUtil实例
public static URLUtil from(String url) {
return new URLUtil(url);
}
// 获取参数的方法
public String getParam(String param) {
return queryParams.get(param);
}
}

View File

@@ -1,4 +1,4 @@
package qaiu.web.test;
package cn.qaiu.parser;
import io.vertx.core.MultiMap;
import io.vertx.core.Vertx;

View File

@@ -1,4 +1,4 @@
package qaiu.web.test;
package cn.qaiu.util;
import cn.qaiu.util.AESUtils;
import org.junit.Assert;

View File

@@ -1,4 +1,4 @@
package qaiu.web.test;
package cn.qaiu.util;
import org.junit.Test;

View File

@@ -0,0 +1,19 @@
package cn.qaiu.util;
import org.junit.Assert;
import org.junit.Test;
import static org.junit.Assert.*;
public class URLUtilTest {
@Test
public void getParam() {
URLUtil util = URLUtil.from("https://i.y.qq.com/v8/playsong.html?ADTAG=cbshare&_wv=1&appshare=android_qq" +
"&appsongtype=1&appversion=13100008&channelId=10036163&hosteuin=7iosow-s7enz&openinqqmusic=1&platform" +
"=11&songmid=000XjcLg0fbRjv&type=0");
Assert.assertEquals(util.getParam("songmid"), "000XjcLg0fbRjv");
Assert.assertEquals(util.getParam("type"), "0");
}
}

View File

@@ -1,54 +0,0 @@
package qaiu.web.test;
import io.vertx.core.MultiMap;
import io.vertx.core.Vertx;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.web.client.WebClient;
import org.junit.Test;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class TestWebClient2 {
@Test
public void matcherHtml() {
Pattern compile = Pattern.compile("class=\"ifr2\" name=.+src=\"(/fn\\?[a-zA-Z0-9_+/=]{16,})\"");
var text = """
<div class="ifr"><!--<iframe class="ifr2" name="1" src="/fn?v2" frameborder="0" scrolling="no"></iframe>-->
<iframe class="ifr2" name="1685001208" src="/fn?UzUBa1oxBmUAYgNsUDUFNVI6BjJfJlchV21TZFU_aVWwANVQzXTBXMlUxUTcLZ1dwUn8DYwQ5AHFVOwdmBjRUPlM2AS9aOgY3AGIDMFA2" frameborder="0" scrolling="no"></iframe>""";
System.out.println(text);
Matcher matcher = compile.matcher(text);
if (matcher.find()) {
System.out.println(matcher.group(0));
System.out.println(matcher.group(1));
}
}
@Test
public void lzClient() {
Vertx vertx = Vertx.vertx();
WebClient client = WebClient.create(vertx);
MultiMap form = MultiMap.caseInsensitiveMultiMap();
// action=downprocess&sign=AGYHOQk4BjdTWgQ7BzcGOlU_bATVSNQMxBDFQZgZoBj4HMFEgWnMOZ1I1A2NWOgUxB20HMlM_aUGoLOgQz&p=e4k4
form.set("action", "downprocess");
form.set("sign", "VzFWaA4_aBzYIAQI9ADBUaARvATVRNlNhUGUBNwBuATkDNFEgXHVVPAZhB2dTP1ZiVD5UYQBpV2EBPwA3");
form.set("p", "e4k4");
client.postAbs("https://wwsd.lanzoue.com/ajaxm.php")
.putHeader("referer", "https://wwsd.lanzoue.com/iFhd00x8k0kh")
.sendForm(form).onSuccess(res -> {
JsonObject jsonObject = res.bodyAsJsonObject();
System.out.println(jsonObject);
vertx.close();
});
//
// https://developer.lanzoug.com/file/?VTMBPwEwU2IGD1dvV2ICblBvU2sENQZhVSZSMAA1WihSOVYsDTZTZlN2UXMFfAZjBzJXJQAxAG5XP1UyXGQGKlVlAXgBbVMpBmNXLFdhAmpQZFN4BCEGbVUiUnIAOloyUj5WZA0PU25TYVE6BWAGNgdlV2IAbQAyV2JValw3BiFVMwElAWFTNgZmVzBXMwIyUDpTYARrBiJVIlIkAGFaaVJiVjMNY1MoUzVRMgV+BjUHaFd9ADwAMVdlVTFcOAYyVWcBYgFqUz4GaVdlVzMCNFBrUzcEOAZgVWJSZQA/WmJSM1Y2DWhTNFMzUTEFYgY3B2VXZgBxAHhXOVUjXCYGclUmATMBLlNuBjRXPFcyAjNQP1NvBG8GPVVqUnIAKFoyUj9WZA02UzpTNFExBWkGMgdtV2IAaQAxV2FVYFwuBilVcwEwATBTcAZtVzBXNQI7UD9TZgRrBjFVY1JlAGlafVInVnENJ1M6UzRRMQVpBjIHbVdiAG0AMldgVWRcJgZyVTwBJgFhUzYGYVczVy0CMVA5U2QEdQY1VWZSYgByWmxSag==
// https://developer.lanzoug.com/file/?B2FWaA4/BDVTWgc/UWRVOQQ7BT1VZFYxUSJUNgE0UiAEbwJ4CDMOOwInU3EKc1w5ATRSIAIzUz1ROVcwATkDLwc3Vi8OYgR+UzYHfFFnVT0EMAUuVXBWPVEmVHQBO1I6BGgCMAgKDjMCMFM4Cm9cbAFjUmcCb1NhUWRXaAFqAyQHYVZyDm4EYVMzB2BRNVVlBG4FNlU6VnJRJlQiAWBSYQQ0AmcIZg51AmRTMApxXG8BblJ4Aj5TYlFjVzMBZQM3BzVWNQ5lBGlTPAc1UTVVYwQ/BWFVaVYwUWZUYwE+UmoEZQJiCG0OaQJiUzMKbVxtAWNSYwJzUytRP1chAXsDdwd0VmQOIQQ5U2EHbFE0VWQEawU5VT5WbVFuVHQBKVI6BGkCMAgzDmcCZVMzCmZcaAFrUmcCaFNlUWNXZwFzAywHIVZnDj8EJ1M4B2BRM1VsBGsFMFU6VmZRb1RgAW5SdQRxAiUIIg5nAmVTMwpmXGgBa1JnAm9TYVFmV2YBewN3B25WcQ5uBGFTNAdjUStVZgRtBTJVJFZlUWJUZAFzUmQEPA==
// https://developer.lanzoug.com/file/?CW9WaAk4BzZUXVRsCz5cMAE+Bj5UZVM0USJUNlRhA3FUPwJ4CTJUYQInASMHflI3ATQGdFdmAW9ROQFmVGwEKAk5Vi8JZQd9VDFULws9XDQBNQYtVHFTOFEmVHRUbgNrVDgCMAkLVGkCMAFqB2JSYgFjBjNXOgEzUWQBPlQ/BCMJb1ZyCWkHYlQ0VDMLb1xsAWsGNVQ7U3dRJlQiVDUDMFRkAmcJZ1QvAmQBYgd8UmEBbgYsV2sBMFFjAWVUMAQwCTtWNQliB2pUO1RmC29cagE6BmJUaFM1UWZUY1RrAztUNQJiCWxUMwJiAWEHYFJjAWMGN1cmAXlRPwF3VC4EcAl6VmQJJgc6VGZUPwtuXG0BbgY6VD9TaFFuVHRUfANrVDkCMAkyVD0CZQFhB2tSZgFrBjNXPgE6UWABM1QmBCsJL1ZnCTgHJFQ/VDMLaVxlAW4GM1Q7U2RRb1RmVDgDJFQhAiUJI1Q9AmUBYQdrUmYBawYzVzoBM1FmATBULgRwCWBWcQlpB2JUM1QwC3FcbwFoBjFUJVNgUWJUZFQmAzVUbA==
}
}

View File

@@ -58,5 +58,7 @@ cache:
ws:
ye:
mne: 30
mqq: 30
mkg: 30

View File

@@ -0,0 +1,45 @@
#@no-cookie-jar
#@no-redirect
https://t1.kugou.com/song.html?id=2bi8Fe9CSV3
###
GET https://www.kugou.com/share/2bi8Fe9CSV3.html?id=2bi8Fe9CSV3
accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
if-modified-since: Mon, 21 Oct 2024 08:45:50 GMT
priority: u=0, i
sec-ch-ua: "Microsoft Edge";v="129", "Not=A?Brand";v="8", "Chromium";v="129"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
sec-fetch-dest: document
sec-fetch-mode: navigate
sec-fetch-site: none
sec-fetch-user: ?1
upgrade-insecure-requests: 1
user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36 Edg/129.0.0.0
###
https://www.kuwo.cn/api/v1/www/music/playUrl?mid=395500809&type=music&httpsStatus=1&reqId=&plat=web_www&from=
Cookie: Hm_Iuvt_cdb524f42f23cer9b268564v7y735ewrq2324=c7nkKBeXXzCyTQ8Wc8DRNYc4Th3f6hTE
Secret: 4067e5c95a650d73865fe3e81feb897a6bf7b58579a3ff335de848ffb0ee31c9058333c0
###
https://nmobi.kuwo.cn/mobi.s?f=kuwo&q=NI8S5evAnmGldi4g47EsqtfDbGsJckckbTQQd2LAgmDPITUWSd51OkjHRFj6xHPEQxNN6u+tD3K2e3HYhbE4U0pUYwqjd2kt
###
https://m.kuwo.cn/newh5/singles/songinfoandlrc?musicId=395500809
###
https://kuwo.cn/api/v1/www/music/playUrl?mid=395500809&type=music&httpsStatus=1&reqId=e09294a0-8f90-11ef-9b50-49e06d70bd68&plat=web_www&from=
###
https://kuwo.cn/play_detail/395500809
###
#@no-cookie-jar
https://www.kuwo.cn/api/v1/www/music/playUrl?mid=395500809&type=music&httpsStatus=1&reqId=&plat=web_www&from=
Cookie: Hm_Iuvt_cdb524f42f23cer9b268564v7y735ewrq2324=eZCHRdwSSYkG4d5XRGYtXrMpAXmGE5mh
Secret: 460ac8ea43431f788d7ccbd67fde84755a88a8a36f88d17748d816dec3b308e402f768e8

File diff suppressed because one or more lines are too long

View File

@@ -199,8 +199,15 @@ GET http://127.0.0.1:6401/parser?url=https://474b.com/file/4015376-131945810
# @no-redirect
GET http://127.0.0.1:6401/parser?url=http://163cn.tv/ykLZJJT
### PASS MQQ
# @no-redirect
GET http://127.0.0.1:6401/parser?url=https://c6.y.qq.com/base/fcgi-bin/u?__=k8gafY6HAQ5Y
### PASS MKG
# @no-redirect
GET http://127.0.0.1:6401/parser?url=https://t1.kugou.com/song.html?id=2bi8Fe9CSV3
### n1
http://127.0.0.1:6401/n1/statisticsInfo

View File

@@ -15,7 +15,7 @@ proxy:
# 1.origin代理地址端口后有目录(包括 / ),转发后地址:代理地址+访问URL目录部分去除location匹配目录
# 2.origin代理地址端口后无任何转发后地址代理地址+访问URL目录部
location:
- path: ~^/(json/|v2/|parser|ye/|lz/|cow/|ec/|fj/|fc/|le/|qq/|ws/|iz/|ce|mne/).*
- path: ~^/(json/|v2/|parser|ye/|lz/|cow/|ec/|fj/|fc/|le/|qq/|ws/|iz/|ce|mne|mqq|mkg/).*
origin: 127.0.0.1:6400
# json/parser -> xxx/parser