mirror of
https://github.com/qaiu/netdisk-fast-download.git
synced 2025-12-16 12:23:03 +00:00
重构蓝奏云解析代码, 加入蓝奏云加密分享解析
This commit is contained in:
@@ -1,21 +1,14 @@
|
||||
package cn.qaiu.lz.common.util;
|
||||
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
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.HttpRequest;
|
||||
import io.vertx.ext.web.client.WebClient;
|
||||
import io.vertx.ext.web.client.WebClientOptions;
|
||||
import org.jsoup.Jsoup;
|
||||
import org.jsoup.nodes.Document;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@@ -27,159 +20,71 @@ import java.util.regex.Pattern;
|
||||
*/
|
||||
public class LzTool {
|
||||
|
||||
public static String parse(String fullUrl) throws Exception {
|
||||
var userAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0" +
|
||||
".3626.121 Safari/537.3";
|
||||
var url = fullUrl.substring(0, fullUrl.lastIndexOf('/') + 1);
|
||||
var id = fullUrl.substring(fullUrl.lastIndexOf('/') + 1);
|
||||
Map<String, String> header = new HashMap<>();
|
||||
header.put("Accept-Language", "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2");
|
||||
header.put("referer", url);
|
||||
public static final String SHARE_URL_PREFIX = "https://wwwa.lanzoui.com";
|
||||
|
||||
/*
|
||||
// 部分链接需要设置安卓UA
|
||||
sec-ch-ua: "Google Chrome";v="111", "Not(A:Brand";v="8", "Chromium";v="111"
|
||||
sec-ch-ua-mobile: ?1
|
||||
sec-ch-ua-platform: "Android"
|
||||
*/
|
||||
var userAgent2 = "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like " +
|
||||
"Gecko) Chrome/111.0.0.0 Mobile Safari/537.36";
|
||||
Map<String, String> header2 = new HashMap<>();
|
||||
header2.put("Accept-Language", "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2");
|
||||
header2.put("sec-ch-ua-mobile", "sec-ch-ua-mobile");
|
||||
header2.put("sec-ch-ua-platform", "Android");
|
||||
header2.put("referer", url);
|
||||
public static Future<String> parse(String data, String code) {
|
||||
Promise<String> promise = Promise.promise();
|
||||
String key = data.indexOf('/') > 0 ? data : SHARE_URL_PREFIX + "/" + data;
|
||||
|
||||
//第一次请求,获取iframe的地址
|
||||
String result = Jsoup.connect(url + id)
|
||||
.userAgent(userAgent)
|
||||
.get()
|
||||
.select(".ifr2")
|
||||
.attr("src");
|
||||
|
||||
//第二次请求得到js里的json数据里的sign
|
||||
result = Jsoup.connect(url + result)
|
||||
.headers(header)
|
||||
.userAgent(userAgent)
|
||||
.get()
|
||||
.html();
|
||||
// System.out.println(result);
|
||||
// 'sign':'AWcGOFprUGFWX1BvBTVXawdrBDZTOAU_bV2FTZFU7W2sBJ1t4DW0FYFIyBmgDZVJgUjAFNV41UGQFNg_c_c' 改下正则TMD
|
||||
// 最近上传竟然没_c_c
|
||||
Matcher matcher = Pattern.compile("'sign'\s*:\s*'([0-9a-zA-Z_]+)'").matcher(result);
|
||||
Map<String, String> params = new LinkedHashMap<>();
|
||||
if (matcher.find()) {
|
||||
String sn = matcher.group(1).replace("'", "");
|
||||
params.put("action", "downprocess");
|
||||
params.put("sign", sn);
|
||||
params.put("ves", "1");
|
||||
// System.out.println(sn);
|
||||
|
||||
} else {
|
||||
throw new IOException();
|
||||
}
|
||||
//第三次请求 通过参数发起post请求,返回json数据
|
||||
result = Jsoup
|
||||
.connect(url + "ajaxm.php")
|
||||
.headers(header)
|
||||
.userAgent(userAgent)
|
||||
.data(params)
|
||||
.post()
|
||||
.text()
|
||||
.replace("\\", "");
|
||||
//json转为map
|
||||
params = new ObjectMapper().readValue(result, new TypeReference<>() {
|
||||
});
|
||||
// System.out.println(params);
|
||||
//通过json的数据拼接出最终的URL发起第最终请求,并得到响应信息头
|
||||
url = params.get("dom") + "/file/" + params.get("url");
|
||||
var headers = Jsoup.connect(url)
|
||||
.ignoreContentType(true)
|
||||
.userAgent(userAgent2)
|
||||
.headers(header2)
|
||||
.followRedirects(false)
|
||||
.execute()
|
||||
.headers();
|
||||
//得到重定向的地址进行重定向
|
||||
url = headers.get("Location");
|
||||
|
||||
return url;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
// String key = "https://wwsd.lanzoue.com/iNvid035jgcb";
|
||||
String key = "https://wwsd.lanzoue.com/icBp6qqj82b";
|
||||
String urlPrefix = "https://lanzoux.com";
|
||||
String code = "QAIU";
|
||||
|
||||
WebClient client = WebClient.create(Vertx.vertx(), new WebClientOptions().setFollowRedirects(false));
|
||||
WebClient client = WebClient.create(VertxHolder.getVertxInstance(),
|
||||
new WebClientOptions().setFollowRedirects(false));
|
||||
client.getAbs(key).send().onSuccess(res -> {
|
||||
String html = res.bodyAsString();
|
||||
// 匹配iframe
|
||||
Pattern compile = Pattern.compile("class=\"ifr2\" name=.+src=\"(/fn\\?[a-zA-Z0-9_+/=]{16,})\"");
|
||||
Pattern compile = Pattern.compile("src=\"(/fn\\?[a-zA-Z0-9_+/=]{16,})\"");
|
||||
Matcher matcher = compile.matcher(html);
|
||||
if (!matcher.find()) {
|
||||
// $.ajax({
|
||||
// type : 'post',
|
||||
// url : '/ajaxm.php',
|
||||
// //data : 'action=downprocess&sign=VTMAPgs6UG&p='+pwd,
|
||||
// data : 'action=downprocess&sign
|
||||
// =VzEBPwAxBzYIAQo1BjYBPVA_bDj1fNgEwUWNTYFUwAzMJL1V2Xj5XMlMzVjhTMVFjUzEHOlM4AjEBNQ_c_c&p
|
||||
// ='+pwd,
|
||||
// //data : 'action=downprocess&sign=VTMAPgs6UG&p='+pwd,
|
||||
// dataType : 'json',
|
||||
// success:function(msg){
|
||||
// var date = msg;
|
||||
// if(date.zt == '1'){
|
||||
// $("#downajax").html("<a href="+date.dom+"/file/"+ date.url +" target=_blank
|
||||
// rel=noreferrer>下载</a>");
|
||||
// }else{
|
||||
// $("#info").text(date.inf);
|
||||
// };
|
||||
//
|
||||
// },
|
||||
// 匹配不到说明需要密码 直接解析并请求ajaxm.php
|
||||
|
||||
// 匹配sign
|
||||
// 没有Iframe说明是加密分享, 匹配sign通过密码请求下载页面
|
||||
Pattern compile2 = Pattern.compile("sign=([0-9a-zA-Z_]{16,})");
|
||||
Matcher matcher2 = compile2.matcher(html);
|
||||
if (!matcher2.find()) {
|
||||
promise.fail(key + ": sign正则匹配失败, 可能分享已失效: " + html);
|
||||
return;
|
||||
}
|
||||
String sign = matcher2.group(1);
|
||||
|
||||
var userAgent2 = "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, " +
|
||||
"like " +
|
||||
"Gecko) Chrome/111.0.0.0 Mobile Safari/537.36";
|
||||
|
||||
HttpRequest<Buffer> bufferHttpRequest = client.postAbs(urlPrefix + "/ajaxm.php");
|
||||
bufferHttpRequest.putHeader("User-Agent", userAgent2);
|
||||
bufferHttpRequest.putHeader("referer", key);
|
||||
bufferHttpRequest.putHeader("sec-ch-ua-platform", "Android");
|
||||
|
||||
bufferHttpRequest.putHeader("Accept-Language", "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2");
|
||||
bufferHttpRequest.putHeader("sec-ch-ua-mobile", "sec-ch-ua-mobile");
|
||||
bufferHttpRequest.sendForm(MultiMap.caseInsensitiveMultiMap()
|
||||
.set("action", "downprocess")
|
||||
.set("sign", sign).set("p", code)).onSuccess(res2 -> {
|
||||
JsonObject urlJson = res2.bodyAsJsonObject();
|
||||
System.out.println(urlJson);
|
||||
String downUrl = urlJson.getString("dom") + "/file/" + urlJson.getString("url");
|
||||
System.out.println(downUrl);
|
||||
client.getAbs(downUrl).send().onSuccess(res3 -> {
|
||||
System.out.println(res3.headers());
|
||||
System.out.println(res3.bodyAsString());
|
||||
});
|
||||
});
|
||||
|
||||
getDownURL(promise, code, key, client, sign);
|
||||
return;
|
||||
}
|
||||
String iframePath = matcher.group(1);
|
||||
System.out.println(iframePath);
|
||||
client.getAbs(urlPrefix + iframePath).send().onSuccess(res2 -> {
|
||||
System.out.println(res2.bodyAsString());
|
||||
client.getAbs(SHARE_URL_PREFIX + iframePath).send().onSuccess(res2 -> {
|
||||
String html2 = res2.bodyAsString();
|
||||
System.out.println(html);
|
||||
Matcher matcher2 = Pattern.compile("'sign'\s*:\s*'([0-9a-zA-Z_]+)'").matcher(html2);
|
||||
if (!matcher2.find()) {
|
||||
promise.fail(SHARE_URL_PREFIX + iframePath + " -> " + key + ": sign正则匹配失败, 可能分享已失效: " + html2);
|
||||
return;
|
||||
}
|
||||
String sign = matcher2.group(1);
|
||||
getDownURL(promise, code, key, client, sign);
|
||||
});
|
||||
});
|
||||
return promise.future();
|
||||
}
|
||||
|
||||
private static void getDownURL(Promise<String> promise, String code, String key, WebClient client, String sign) {
|
||||
MultiMap headers = MultiMap.caseInsensitiveMultiMap();
|
||||
var userAgent2 = "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, " +
|
||||
"like " +
|
||||
"Gecko) Chrome/111.0.0.0 Mobile Safari/537.36";
|
||||
headers.set("User-Agent", userAgent2);
|
||||
headers.set("referer", key);
|
||||
headers.set("sec-ch-ua-platform", "Android");
|
||||
headers.set("Accept-Language", "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2");
|
||||
headers.set("sec-ch-ua-mobile", "sec-ch-ua-mobile");
|
||||
|
||||
client.postAbs(SHARE_URL_PREFIX + "/ajaxm.php").putHeaders(headers).sendForm(MultiMap
|
||||
.caseInsensitiveMultiMap()
|
||||
.set("action", "downprocess")
|
||||
.set("sign", sign).set("p", code)).onSuccess(res2 -> {
|
||||
JsonObject urlJson = res2.bodyAsJsonObject();
|
||||
if (urlJson.getInteger("zt") != 1) {
|
||||
promise.fail(urlJson.getString("inf"));
|
||||
return;
|
||||
}
|
||||
String downUrl = urlJson.getString("dom") + "/file/" + urlJson.getString("url");
|
||||
client.getAbs(downUrl).putHeaders(headers).send().onSuccess(res3 -> {
|
||||
promise.complete(res3.headers().get("Location"));
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,12 +70,11 @@ public class ServerApi {
|
||||
promise.complete();
|
||||
}).onFailure(t -> promise.fail(t.fillInStackTrace()));
|
||||
} else if (url.contains("lanzou")) {
|
||||
String urlDownload;
|
||||
try {
|
||||
urlDownload = LzTool.parse(url);
|
||||
log.info("url = {}", urlDownload);
|
||||
response.putHeader("location", urlDownload).setStatusCode(302).end();
|
||||
LzTool.parse(url, pwd).onSuccess(resUrl -> {
|
||||
response.putHeader("location", resUrl).setStatusCode(302).end();
|
||||
promise.complete();
|
||||
}).onFailure(t -> promise.fail(t.fillInStackTrace()));
|
||||
} catch (Exception e) {
|
||||
promise.fail(e);
|
||||
}
|
||||
@@ -94,11 +93,30 @@ public class ServerApi {
|
||||
}
|
||||
|
||||
@RouteMapping(value = "/lz/:id", method = RouteMethod.GET)
|
||||
public void lzParse(HttpServerResponse response, String id) throws Exception {
|
||||
var url = "https://wwsd.lanzoue.com/" + id;
|
||||
var urlDownload = LzTool.parse(url);
|
||||
log.info("url = {}", urlDownload);
|
||||
response.putHeader("location", urlDownload).setStatusCode(302).end();
|
||||
public void lzParse(HttpServerResponse response, String id) {
|
||||
String code = "";
|
||||
if (id.contains("@")) {
|
||||
String[] ids = id.split("@");
|
||||
id = ids[0];
|
||||
code = ids[1];
|
||||
}
|
||||
LzTool.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/lz/:id", method = RouteMethod.GET)
|
||||
public Future<String> lzParseJson(HttpServerResponse response, String id) {
|
||||
String code = "";
|
||||
if (id.contains("@")) {
|
||||
String[] ids = id.split("@");
|
||||
id = ids[0];
|
||||
code = ids[1];
|
||||
}
|
||||
return LzTool.parse(id, code);
|
||||
}
|
||||
|
||||
@RouteMapping(value = "/cow/:id", method = RouteMethod.GET)
|
||||
@@ -108,14 +126,6 @@ public class ServerApi {
|
||||
response.putHeader("location", urlDownload).setStatusCode(302).end();
|
||||
}
|
||||
|
||||
@RouteMapping(value = "/json/lz/:id", method = RouteMethod.GET)
|
||||
public JsonResult<String> lzParseJson(HttpServerResponse response, String id) throws Exception {
|
||||
var url = "https://wwsd.lanzoue.com/" + id;
|
||||
var urlDownload = LzTool.parse(url);
|
||||
log.info("url = {}", urlDownload);
|
||||
return JsonResult.data(urlDownload);
|
||||
}
|
||||
|
||||
@RouteMapping(value = "/json/cow/:id", method = RouteMethod.GET)
|
||||
public JsonResult<String> cowParseJson(HttpServerResponse response, String id) throws Exception {
|
||||
var url = "https://cowtransfer.com/s/" + id;
|
||||
|
||||
@@ -16,7 +16,11 @@ GET http://127.0.0.1:6400/cow/9a644fe3e3a748
|
||||
|
||||
###
|
||||
# @no-redirect
|
||||
GET http://127.0.0.1:6400/lz/ia2cntg
|
||||
GET http://127.0.0.1:6400/lz/i6SqHmp1yfc
|
||||
|
||||
###
|
||||
# @no-redirect
|
||||
GET http://127.0.0.1:6400/lz/icBp6qqj82b@QAIU
|
||||
|
||||
###
|
||||
GET http://127.0.0.1:6400/json/lz/ia2cntg
|
||||
|
||||
Reference in New Issue
Block a user