mirror of
https://github.com/qaiu/netdisk-fast-download.git
synced 2025-12-16 20:33:03 +00:00
添加123云盘直链解析
This commit is contained in:
@@ -1,11 +1,38 @@
|
||||
package cn.qaiu.lz.common.util;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.text.ParseException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class CommonUtils {
|
||||
|
||||
public static String parseURL(String urlPrefix, String url) {
|
||||
public static String adaptShortPaths(String urlPrefix, String url) {
|
||||
if (!url.startsWith(urlPrefix)) {
|
||||
url = urlPrefix + url;
|
||||
}
|
||||
if (url.endsWith(".html")) {
|
||||
url = url.substring(0, url.length() - 5);
|
||||
}
|
||||
return url.substring(urlPrefix.length());
|
||||
}
|
||||
|
||||
public static Map<String, String> getURLParams(String url) throws MalformedURLException {
|
||||
URL fullUrl = new URL(url);
|
||||
String query = fullUrl.getQuery();
|
||||
String[] params = query.split("&");
|
||||
Map<String, String> map = new HashMap<>();
|
||||
for (String param : params) {
|
||||
if (!param.contains("=")) {
|
||||
throw new RuntimeException("解析URL异常: 匹配不到参数中的=");
|
||||
}
|
||||
int endIndex = param.indexOf('=');
|
||||
String key = param.substring(0, endIndex);
|
||||
String value = param.substring(endIndex + 1);
|
||||
map.put(key, value);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ public class FcTool {
|
||||
"&scenario=share&unique_name={uname}";
|
||||
|
||||
public static Future<String> parse(String data, String code) {
|
||||
String dataKey = CommonUtils.parseURL(SHARE_URL_PREFIX, data);
|
||||
String dataKey = CommonUtils.adaptShortPaths(SHARE_URL_PREFIX, data);
|
||||
|
||||
Promise<String> promise = Promise.promise();
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ public class FjTool {
|
||||
"&devType=6&uuid={uuid}×tamp={ts}&auth={auth}";
|
||||
|
||||
public static Future<String> parse(String data) {
|
||||
String dataKey = CommonUtils.parseURL(SHARE_URL_PREFIX, data);
|
||||
String dataKey = CommonUtils.adaptShortPaths(SHARE_URL_PREFIX, data);
|
||||
|
||||
Promise<String> promise = Promise.promise();
|
||||
WebClient client = WebClient.create(VertxHolder.getVertxInstance(),
|
||||
|
||||
@@ -27,7 +27,7 @@ public class UcTool {
|
||||
private static final String THIRD_REQUEST_URL = API_URL_PREFIX + "file/download?entry=ft&fr=pc&pr=UCBrowser";
|
||||
|
||||
public static Future<String> parse(String data, String code) {
|
||||
var dataKey = CommonUtils.parseURL(SHARE_URL_PREFIX, data);
|
||||
var dataKey = CommonUtils.adaptShortPaths(SHARE_URL_PREFIX, data);
|
||||
var passcode = (code == null) ? "" : code;
|
||||
Promise<String> promise = Promise.promise();
|
||||
var client = WebClient.create(VertxHolder.getVertxInstance());
|
||||
|
||||
102
web-service/src/main/java/cn/qaiu/lz/common/util/YeTool.java
Normal file
102
web-service/src/main/java/cn/qaiu/lz/common/util/YeTool.java
Normal file
@@ -0,0 +1,102 @@
|
||||
package cn.qaiu.lz.common.util;
|
||||
|
||||
import cn.qaiu.vx.core.util.VertxHolder;
|
||||
import io.vertx.core.Future;
|
||||
import io.vertx.core.Promise;
|
||||
import io.vertx.core.json.JsonObject;
|
||||
import io.vertx.ext.web.client.WebClient;
|
||||
import io.vertx.uritemplate.UriTemplate;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.util.Base64;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* 123网盘
|
||||
*/
|
||||
public class YeTool {
|
||||
public static final String SHARE_URL_PREFIX = "https://www.123pan.com/s/";
|
||||
public static final String FIRST_REQUEST_URL = SHARE_URL_PREFIX + "{key}.html";
|
||||
private static final String GET_FILE_INFO_URL = "https://www.123pan.com/a/api/share/get?limit=100&next=1&orderBy" +
|
||||
"=file_name&orderDirection=asc&shareKey={shareKey}&SharePwd={pwd}&ParentFileId=0&Page=1&event" +
|
||||
"=homeListFile&operateType=1";
|
||||
|
||||
public static Future<String> parse(String data, String code) {
|
||||
|
||||
String dataKey = CommonUtils.adaptShortPaths(SHARE_URL_PREFIX, data);
|
||||
Promise<String> promise = Promise.promise();
|
||||
WebClient client = WebClient.create(VertxHolder.getVertxInstance());
|
||||
|
||||
client.getAbs(UriTemplate.of(FIRST_REQUEST_URL)).setTemplateParam("key", dataKey).send().onSuccess(res -> {
|
||||
|
||||
String html = res.bodyAsString();
|
||||
Pattern compile = Pattern.compile("window.g_initialProps\\s*=\\s*(.*);");
|
||||
Matcher matcher = compile.matcher(html);
|
||||
|
||||
if (!matcher.find()) {
|
||||
System.out.println("err");
|
||||
return;
|
||||
}
|
||||
String fileInfoString = matcher.group(1);
|
||||
JsonObject fileInfoJson = new JsonObject(fileInfoString);
|
||||
JsonObject resJson = fileInfoJson.getJsonObject("res");
|
||||
JsonObject resListJson = fileInfoJson.getJsonObject("reslist");
|
||||
|
||||
if (resJson == null || resJson.getInteger("code") != 0) {
|
||||
promise.fail(dataKey + " 解析到异常JSON: "+resJson);
|
||||
return;
|
||||
}
|
||||
String shareKey = resJson.getJsonObject("data").getString("ShareKey");
|
||||
if (resListJson == null || resListJson.getInteger("code") != 0) {
|
||||
// 加密分享
|
||||
if (StringUtils.isNotEmpty(code)) {
|
||||
client.getAbs(UriTemplate.of(GET_FILE_INFO_URL))
|
||||
.setTemplateParam("shareKey", shareKey)
|
||||
.setTemplateParam("pwd", code)
|
||||
.send().onSuccess(res2 -> {
|
||||
JsonObject infoJson = res2.bodyAsJsonObject();
|
||||
if (infoJson.getInteger("code") != 0) {
|
||||
return;
|
||||
}
|
||||
JsonObject getFileInfoJson =
|
||||
infoJson.getJsonObject("data").getJsonArray("InfoList").getJsonObject(0);
|
||||
getFileInfoJson.put("ShareKey", shareKey);
|
||||
getDownUrl(promise, client, getFileInfoJson);
|
||||
});
|
||||
} else {
|
||||
promise.fail(dataKey + " 该分享需要密码");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
JsonObject reqBodyJson = resListJson.getJsonObject("data").getJsonArray("InfoList").getJsonObject(0);
|
||||
reqBodyJson.put("ShareKey", shareKey);
|
||||
getDownUrl(promise, client, reqBodyJson);
|
||||
});
|
||||
|
||||
return promise.future();
|
||||
}
|
||||
|
||||
private static void getDownUrl(Promise<String> promise, WebClient client, JsonObject reqBodyJson) {
|
||||
System.out.println(reqBodyJson);
|
||||
client.postAbs("https://www.123pan.com/a/api/share/download/info").sendJsonObject(reqBodyJson).onSuccess(res2 -> {
|
||||
JsonObject downURLJson = res2.bodyAsJsonObject();
|
||||
System.out.println(downURLJson);
|
||||
if (downURLJson.getInteger("code") != 0) {
|
||||
return;
|
||||
}
|
||||
String downURL = downURLJson.getJsonObject("data").getString("DownloadURL");
|
||||
try {
|
||||
Map<String, String> urlParams = CommonUtils.getURLParams(downURL);
|
||||
String params = urlParams.get("params");
|
||||
byte[] decodeByte = Base64.getDecoder().decode(params);
|
||||
promise.complete(new String(decodeByte));
|
||||
} catch (MalformedURLException e) {
|
||||
promise.fail("urlParams解析异常" + e.getMessage());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -64,6 +64,11 @@ public class ServerApi {
|
||||
response.putHeader("location", resUrl).setStatusCode(302).end();
|
||||
promise.complete();
|
||||
}).onFailure(t -> promise.fail(t.fillInStackTrace()));
|
||||
} else if (url.contains(YeTool.SHARE_URL_PREFIX)) {
|
||||
YeTool.parse(url, pwd).onSuccess(resUrl -> {
|
||||
response.putHeader("location", resUrl).setStatusCode(302).end();
|
||||
promise.complete();
|
||||
}).onFailure(t -> promise.fail(t.fillInStackTrace()));
|
||||
} else if (url.contains("lanzou")) {
|
||||
String urlDownload;
|
||||
try {
|
||||
@@ -196,4 +201,30 @@ public class ServerApi {
|
||||
}
|
||||
return FcTool.parse(id, code);
|
||||
}
|
||||
|
||||
@RouteMapping(value = "/ye/:id", method = RouteMethod.GET)
|
||||
public void YeParse(HttpServerResponse response, String id) {
|
||||
String code = "";
|
||||
if (id.contains("@")) {
|
||||
String[] ids = id.split("@");
|
||||
id = ids[0];
|
||||
code = ids[1];
|
||||
}
|
||||
YeTool.parse(id, code).onSuccess(resUrl -> response.putHeader("location", resUrl)
|
||||
.setStatusCode(302).end()).onFailure(t -> {
|
||||
response.putHeader(CONTENT_TYPE, "text/html;charset=utf-8");
|
||||
response.end(t.getMessage());
|
||||
});
|
||||
}
|
||||
|
||||
@RouteMapping(value = "/json/ye/:id", method = RouteMethod.GET)
|
||||
public Future<String> YeParseJson(HttpServerResponse response, String id) {
|
||||
String code = "";
|
||||
if (id.contains("@")) {
|
||||
String[] ids = id.split("@");
|
||||
id = ids[0];
|
||||
code = ids[1];
|
||||
}
|
||||
return YeTool.parse(id, code);
|
||||
}
|
||||
}
|
||||
|
||||
84
web-service/src/main/resources/http-tools/pan-ye.http
Normal file
84
web-service/src/main/resources/http-tools/pan-ye.http
Normal file
@@ -0,0 +1,84 @@
|
||||
### 123网盘
|
||||
# auto_redirect 0
|
||||
# filename libc++_shared.so
|
||||
# r L7PQ1A
|
||||
# s 16864619537565b1bbecb509ef377f6e8487a6a99b
|
||||
# t 1686461953
|
||||
# v 5
|
||||
# x-mf-biz-cid 4010bf7a-c68c-42d2-bdf4-13e2b5545904-a0d664
|
||||
# @no-redirect
|
||||
# @no-cookie-jar
|
||||
https://download-cdn.123pan.cn/123-670/af2b7957/1813857424-0/af2b7957d3f4062a06a7b9ef6a3d5a9e?t=1686461953&s=16864619537565b1bbecb509ef377f6e8487a6a99b&r=L7PQ1A&filename=libc%2B%2B_shared.so&auto_redirect=0
|
||||
|
||||
|
||||
|
||||
### 获取下载
|
||||
# FileID S3keyFlag Size Etag
|
||||
|
||||
# @no-redirect
|
||||
# @no-cookie-jar
|
||||
POST https://www.123pan.com/a/api/share/download/info
|
||||
Content-Type:application/json;charset=UTF-8
|
||||
|
||||
{
|
||||
"ShareKey": "iaKtVv-qOECd",
|
||||
"FileID": 2193733,
|
||||
"S3keyFlag": "1813857424-0",
|
||||
"Size": 976880,
|
||||
"Etag": "af2b7957d3f4062a06a7b9ef6a3d5a9e"
|
||||
}
|
||||
|
||||
###
|
||||
POST https://www.123pan.com/a/api/share/download/info
|
||||
Content-Type:application/json;charset=UTF-8
|
||||
|
||||
{
|
||||
"res": {
|
||||
"code": 0,
|
||||
"message": "ok",
|
||||
"data": {
|
||||
"UserNickName": "15********0",
|
||||
"UserID": 1815268665,
|
||||
"ShareName": "libc++_shared.so",
|
||||
"HasPwd": false,
|
||||
"Expiration": "2099-01-01T00:00:00+08:00",
|
||||
"CreateAt": "2023-06-10T13:36:44+08:00",
|
||||
"Expired": false,
|
||||
"ShareKey": "iaKtVv-qOECd",
|
||||
"HeadImage": "https://thirdwx.qlogo.cn/mmopen/vi_32/0G2KQrJ4105icYkK0zBADdHhxyM2W7Q5jf0xh9OyfOM6INOaB3Mgov6CUjdibz43ZvhnZm2MLe8zgd1cZv4C72XQ/132",
|
||||
"IsVip": false,
|
||||
"DisplayStatus": 1
|
||||
}
|
||||
},
|
||||
"reslist": {
|
||||
"code": 0,
|
||||
"message": "ok",
|
||||
"data": {
|
||||
"Next": "-1",
|
||||
"Len": 1,
|
||||
"IsFirst": true,
|
||||
"Expired": false,
|
||||
"InfoList": [
|
||||
{
|
||||
"FileId": 2193733,
|
||||
"FileName": "libc++_shared.so",
|
||||
"Type": 0,
|
||||
"Size": 976880,
|
||||
"ContentType": "0",
|
||||
"S3KeyFlag": "1813857424-0",
|
||||
"CreateAt": "2023-06-10T13:36:12+08:00",
|
||||
"UpdateAt": "2023-06-10T13:36:44+08:00",
|
||||
"Etag": "af2b7957d3f4062a06a7b9ef6a3d5a9e",
|
||||
"DownloadUrl": "",
|
||||
"Status": 5,
|
||||
"ParentFileId": 0,
|
||||
"Category": 0,
|
||||
"PunishFlag": 0,
|
||||
"StorageNode": "m0",
|
||||
"checked": true
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"publicPath": "https://www.123pan.com/a/api/"
|
||||
}
|
||||
@@ -152,3 +152,14 @@ GET http://127.0.0.1:6400/json/fc/30646fefc8bf936a4766ab8a5e
|
||||
GET http://127.0.0.1:6400/fc/e5079007dc31226096628870c7@QAIU
|
||||
|
||||
#https://v2.fangcloud.com/sharing/e5079007dc31226096628870c7
|
||||
|
||||
### 123
|
||||
GET http://127.0.0.1:6400/json/ye/iaKtVv-qOECd
|
||||
|
||||
### 123
|
||||
# @no-redirect
|
||||
GET http://127.0.0.1:6400/ye/iaKtVv-qOECd@asdads
|
||||
|
||||
### 123
|
||||
# @no-redirect
|
||||
GET http://127.0.0.1:6400/parser?url=https://www.123pan.com/s/iaKtVv-6OECd.html&pwd=DcGe
|
||||
|
||||
Reference in New Issue
Block a user