- 加入360亿方云直链解析

- 优化代码
This commit is contained in:
QAIU
2023-06-10 13:29:22 +08:00
parent 635c639bf5
commit 3f4f9fa76b
7 changed files with 274 additions and 65 deletions

View File

@@ -0,0 +1,105 @@
package cn.qaiu.lz.common.util;
import cn.qaiu.vx.core.util.VertxHolder;
import io.vertx.core.Future;
import io.vertx.core.MultiMap;
import io.vertx.core.Promise;
import io.vertx.core.Vertx;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.web.client.HttpResponse;
import io.vertx.ext.web.client.WebClient;
import io.vertx.ext.web.client.WebClientOptions;
import io.vertx.ext.web.client.WebClientSession;
import io.vertx.uritemplate.UriTemplate;
import org.apache.commons.lang3.StringUtils;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* 亿方云
*/
public class FcTool {
public static final String SHARE_URL_PREFIX = "https://v2.fangcloud.com/sharing/";
public static final String SHARE_URL_PREFIX2 = "https://v2.fangcloud.cn/sharing/";
private static final String DOWN_REQUEST_URL = "https://v2.fangcloud.cn/apps/files/download?file_id={fid}" +
"&scenario=share&unique_name={uname}";
public static Future<String> parse(String data, String code) {
String dataKey = CommonUtils.parseURL(SHARE_URL_PREFIX, data);
Promise<String> promise = Promise.promise();
Vertx vertx = VertxHolder.getVertxInstance();
WebClient client = WebClient.create(vertx);
WebClientSession sClient = WebClientSession.create(client);
// 第一次请求 自动重定向
sClient.getAbs(SHARE_URL_PREFIX + dataKey).send().onSuccess(res -> {
// 判断是否是加密分享
if (StringUtils.isNotEmpty(code)) {
// 获取requesttoken
String html = res.bodyAsString();
Pattern compile = Pattern.compile("name=\"requesttoken\"\\s+value=\"([a-zA-Z0-9_+=]+)\"");
Matcher matcher = compile.matcher(html);
if (!matcher.find()) {
promise.fail(SHARE_URL_PREFIX + " 未匹配到加密分享的密码输入页面的requesttoken: \n" + html);
return;
}
String token = matcher.group(1);
sClient.postAbs(SHARE_URL_PREFIX2 + dataKey).sendForm(MultiMap.caseInsensitiveMultiMap()
.set("requesttoken", token)
.set("password", code)).onSuccess(res2 -> {
if (res2.statusCode() == 302) {
sClient.getAbs(res2.getHeader("Location")).send().onSuccess(res3 -> {
getDownURL(dataKey, promise, res3, sClient);
});
} else {
promise.fail(SHARE_URL_PREFIX + " 密码跳转后获取重定向失败 \n" + html);
}
});
return;
}
getDownURL(dataKey, promise, res, sClient);
});
return promise.future();
}
private static void getDownURL(String dataKey, Promise<String> promise, HttpResponse<Buffer> res,
WebClientSession sClient) {
// 从HTML中找到文件id
String html = res.bodyAsString();
Pattern compile = Pattern.compile("id=\"typed_id\"\\s+value=\"file_(\\d+)\"");
Matcher matcher = compile.matcher(html);
if (!matcher.find()) {
promise.fail(SHARE_URL_PREFIX + " 未匹配到文件id(typed_id): \n" + html);
return;
}
String fid = matcher.group(1);
// 创建一个不自动重定向的WebClientSession
WebClient clientNoRedirects = WebClient.create(VertxHolder.getVertxInstance(),
new WebClientOptions().setFollowRedirects(false));
WebClientSession sClientNoRedirects = WebClientSession.create(clientNoRedirects, sClient.cookieStore());
// 第二次请求
sClientNoRedirects.getAbs(UriTemplate.of(DOWN_REQUEST_URL))
.setTemplateParam("fid", fid)
.setTemplateParam("unique_name", dataKey).send().onSuccess(res2 -> {
JsonObject resJson;
try {
resJson = res2.bodyAsJsonObject();
} catch (Exception e) {
promise.fail(DOWN_REQUEST_URL + " 第二次请求没有返回JSON, 可能下载受限: " + res2.bodyAsString());
return;
}
if (!resJson.getBoolean("success")) {
promise.fail(DOWN_REQUEST_URL + " 第二次请求未得到正确相应: " + resJson);
return;
}
promise.complete(resJson.getString("download_url"));
});
}
}

View File

@@ -3,6 +3,7 @@ package cn.qaiu.lz.common.util;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import java.io.IOException;
import java.util.HashMap;
@@ -90,6 +91,7 @@ public class LzTool {
.headers();
//得到重定向的地址进行重定向
url = headers.get("Location");
return url;
}
}

View File

@@ -42,8 +42,30 @@ public class ServerApi {
@RouteMapping(value = "/parser", method = RouteMethod.GET)
public Future<Void> parse(HttpServerResponse response, HttpServerRequest request, String url, String pwd) {
Promise<Void> promise = Promise.promise();
if (url.contains("lanzou")) {
String urlDownload = null;
if (url.contains(EcTool.EC_HOST)) {
// 默认读取Url参数会被截断手动获取一下其他参数
String data = request.getParam("data");
EcTool.parse(data).onSuccess(resUrl -> {
response.putHeader("location", resUrl).setStatusCode(302).end();
promise.complete();
}).onFailure(t -> promise.fail(t.fillInStackTrace()));
} else if (url.contains(UcTool.SHARE_URL_PREFIX)) {
UcTool.parse(url, pwd).onSuccess(resUrl -> {
response.putHeader("location", resUrl).setStatusCode(302).end();
promise.complete();
}).onFailure(t -> promise.fail(t.fillInStackTrace()));
} else if (url.contains(FjTool.SHARE_URL_PREFIX)) {
FjTool.parse(url).onSuccess(resUrl -> {
response.putHeader("location", resUrl).setStatusCode(302).end();
promise.complete();
}).onFailure(t -> promise.fail(t.fillInStackTrace()));
} else if (url.contains(FcTool.SHARE_URL_PREFIX)) {
FcTool.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 {
urlDownload = LzTool.parse(url);
log.info("url = {}", urlDownload);
@@ -53,7 +75,7 @@ public class ServerApi {
promise.fail(e);
}
} else if (url.contains("cowtransfer.com")) {
String urlDownload = null;
String urlDownload;
try {
urlDownload = CowTool.parse(url);
response.putHeader("location", urlDownload).setStatusCode(302).end();
@@ -62,29 +84,6 @@ public class ServerApi {
promise.fail(e);
}
} else if (url.contains(EcTool.EC_HOST)) {
// 默认读取Url参数会被截断手动获取一下其他参数
String data = request.getParam("data");
EcTool.parse(data).onSuccess(resUrl -> {
response.putHeader("location", resUrl).setStatusCode(302).end();
promise.complete();
}).onFailure(t -> {
promise.fail(t.fillInStackTrace());
});
} else if (url.contains(UcTool.SHARE_URL_PREFIX)) {
UcTool.parse(url, pwd).onSuccess(resUrl -> {
response.putHeader("location", resUrl).setStatusCode(302).end();
promise.complete();
}).onFailure(t -> {
promise.fail(t.fillInStackTrace());
});
} else if (url.contains(FjTool.SHARE_URL_PREFIX)) {
FjTool.parse(url).onSuccess(resUrl -> {
response.putHeader("location", resUrl).setStatusCode(302).end();
promise.complete();
}).onFailure(t -> {
promise.fail(t.fillInStackTrace());
});
}
return promise.future();
}
@@ -120,9 +119,8 @@ public class ServerApi {
@RouteMapping(value = "/ec/:id", method = RouteMethod.GET)
public void ecParse(HttpServerResponse response, String id) {
EcTool.parse(id).onSuccess(resUrl -> {
response.putHeader("location", resUrl).setStatusCode(302).end();
}).onFailure(t -> {
EcTool.parse(id).onSuccess(resUrl -> response.putHeader("location", resUrl)
.setStatusCode(302).end()).onFailure(t -> {
response.putHeader(CONTENT_TYPE, "text/html;charset=utf-8");
response.end(t.getMessage());
});
@@ -136,14 +134,13 @@ public class ServerApi {
@RouteMapping(value = "/uc/:id", method = RouteMethod.GET)
public void ucParse(HttpServerResponse response, String id) {
String code = "";
if (id.contains("#")) {
String[] ids = id.split("#");
if (id.contains("$")) {
String[] ids = id.split("\\$");
id = ids[0];
code = ids[1];
}
UcTool.parse(id, code).onSuccess(resUrl -> {
response.putHeader("location", resUrl).setStatusCode(302).end();
}).onFailure(t -> {
UcTool.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());
});
@@ -152,8 +149,8 @@ public class ServerApi {
@RouteMapping(value = "/json/uc/:id", method = RouteMethod.GET)
public Future<String> ucParseJson(String id) {
String code = "";
if (id.contains("#")) {
String[] ids = id.split("#");
if (id.contains("$")) {
String[] ids = id.split("\\$");
id = ids[0];
code = ids[1];
}
@@ -162,9 +159,8 @@ public class ServerApi {
@RouteMapping(value = "/fj/:id", method = RouteMethod.GET)
public void fjParse(HttpServerResponse response, String id) {
FjTool.parse(id).onSuccess(resUrl -> {
response.putHeader("location", resUrl).setStatusCode(302).end();
}).onFailure(t -> {
FjTool.parse(id).onSuccess(resUrl -> response.putHeader("location", resUrl)
.setStatusCode(302).end()).onFailure(t -> {
response.putHeader(CONTENT_TYPE, "text/html;charset=utf-8");
response.end(t.getMessage());
});
@@ -174,4 +170,30 @@ public class ServerApi {
public Future<String> fjParseJson(HttpServerResponse response, String id) {
return FjTool.parse(id);
}
@RouteMapping(value = "/fc/:id", method = RouteMethod.GET)
public void fcParse(HttpServerResponse response, String id) {
String code = "";
if (id.contains("$")) {
String[] ids = id.split("\\$");
id = ids[0];
code = ids[1];
}
FcTool.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/fc/:id", method = RouteMethod.GET)
public Future<String> fcParseJson(HttpServerResponse response, String id) {
String code = "";
if (id.contains("$")) {
String[] ids = id.split("\\$");
id = ids[0];
code = ids[1];
}
return FcTool.parse(id, code);
}
}