百度扫码登录
This commit is contained in:
parent
9afcc6e32a
commit
e67b2d874a
|
|
@ -1,37 +1,256 @@
|
||||||
package com.github.catvod.api;
|
package com.github.catvod.api
|
||||||
|
|
||||||
|
import android.app.AlertDialog
|
||||||
|
import android.content.DialogInterface
|
||||||
|
import android.graphics.Color
|
||||||
|
import android.graphics.drawable.ColorDrawable
|
||||||
|
import android.text.TextUtils
|
||||||
|
import android.view.Gravity
|
||||||
|
import android.widget.FrameLayout
|
||||||
|
import android.widget.ImageView
|
||||||
|
import com.github.catvod.bean.BD.Cache
|
||||||
|
import com.github.catvod.bean.yun.User
|
||||||
|
import com.github.catvod.crawler.SpiderDebug
|
||||||
|
import com.github.catvod.net.OkHttp
|
||||||
|
import com.github.catvod.spider.Init
|
||||||
|
import com.github.catvod.utils.*
|
||||||
|
import okhttp3.Headers
|
||||||
|
import okhttp3.Request
|
||||||
|
import org.apache.commons.lang3.StringEscapeUtils
|
||||||
|
import java.io.File
|
||||||
|
import java.io.IOException
|
||||||
|
import java.io.UnsupportedEncodingException
|
||||||
|
import java.util.concurrent.Executors
|
||||||
|
import java.util.concurrent.ScheduledExecutorService
|
||||||
|
import java.util.concurrent.TimeUnit
|
||||||
|
import kotlin.concurrent.Volatile
|
||||||
|
|
||||||
|
|
||||||
|
class BaiDuYunHandler private constructor() {
|
||||||
|
private val cache: Cache
|
||||||
|
private var service: ScheduledExecutorService? = null
|
||||||
|
private var dialog: AlertDialog? = null
|
||||||
|
private var cookies = ""
|
||||||
|
private val headers = mapOf(
|
||||||
|
"User-Agent" to "Mozilla/5.0 (Linux; Android 12; SM-X800) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.40 Safari/537.36",
|
||||||
|
"Accept" to "application/json, text/plain, */*",
|
||||||
|
"Content-Type" to "application/x-www-form-urlencoded",
|
||||||
|
"Origin" to "https://pan.baidu.com",
|
||||||
|
"Referer" to "https://pan.baidu.com/"
|
||||||
|
)
|
||||||
|
|
||||||
import com.github.catvod.bean.BD.Cache;
|
fun getCache(): File {
|
||||||
import com.github.catvod.bean.yun.User;
|
return Path.tv("bd")
|
||||||
import com.github.catvod.utils.Path;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
|
|
||||||
public class BaiDuYunHandler {
|
|
||||||
|
|
||||||
private final Cache cache;
|
|
||||||
|
|
||||||
public File getCache() {
|
|
||||||
return Path.tv("bd");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private BaiDuYunHandler() {
|
init {
|
||||||
cache = Cache.objectFrom(Path.read(getCache()));
|
cache = Cache.objectFrom(Path.read(getCache()))
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class Loader {
|
private object Loader {
|
||||||
static volatile BaiDuYunHandler INSTANCE = new BaiDuYunHandler();
|
@Volatile
|
||||||
|
var INSTANCE: BaiDuYunHandler = BaiDuYunHandler()
|
||||||
}
|
}
|
||||||
|
|
||||||
public static BaiDuYunHandler get() {
|
val token: String
|
||||||
return BaiDuYunHandler.Loader.INSTANCE;
|
get() {
|
||||||
|
val user: User = cache.getUser()
|
||||||
|
return user.getCookie()
|
||||||
|
//return "cGM6MTg4OTY3ODE2MDE6eTM1Tjd1dG58MXxSQ1N8MTc1NDQ2OTgwNzEyOXxzMlN0T1VEV3lOVmF5V3pNbGFfM2tJbVp1ZmlqSHBqaEhTSzVyNHZqVXNRLmlhV3loSUxHNDFkMUI5N1BqXzhWN0dtVWtKLnBTclhpNGpZU1EuTGZWMTV3MVFoZmNpcEVoZkxUV2tvYjB0bkFTYV9RTUhhaHhveWx6YkdmcEhQdjNCS1lrbnp1LkxaWDdKOE40YkNNRjkzT3piNmx2Y0d3TWdVUkl5b18ubVUt";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
@JvmStatic
|
||||||
|
fun get(): BaiDuYunHandler {
|
||||||
|
return Loader.INSTANCE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Throws(java.lang.Exception::class)
|
||||||
|
fun startScan(): ByteArray {
|
||||||
|
val result = loginByQRCode()
|
||||||
|
// Step 2: Get QR Code
|
||||||
|
val byteStr: ByteArray = downloadQRCode(result["qrCodeImageUrl"]!!);
|
||||||
|
|
||||||
|
Init.run(Runnable { showQRCode(byteStr) })
|
||||||
|
// Step 3: Check login status
|
||||||
|
|
||||||
|
Init.execute(Runnable {
|
||||||
|
startService(
|
||||||
|
result["sign"]!!
|
||||||
|
)
|
||||||
|
})
|
||||||
|
return byteStr
|
||||||
|
}
|
||||||
|
|
||||||
|
@Throws(IOException::class)
|
||||||
|
fun downloadQRCode(url: String): ByteArray {
|
||||||
|
val headers: MutableMap<String?, String?> = HashMap<String?, String?>()
|
||||||
|
headers.put(
|
||||||
|
"user-agent",
|
||||||
|
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
val request = Request.Builder().url(url).headers(Headers.of(headers)).build()
|
||||||
|
val response = OkHttp.newCall(request)
|
||||||
|
if (response.code() == 200) {
|
||||||
|
return response.body()!!.bytes()
|
||||||
|
}
|
||||||
|
return "".toByteArray()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun loginByQRCode(): Map<String, String> {
|
||||||
|
return try {
|
||||||
|
// 获取登录二维码
|
||||||
|
val timestamp = System.currentTimeMillis()
|
||||||
|
val qrCodeUrl = "https://passport.baidu.com/v2/api/getqrcode?lp=pc&_=$timestamp"
|
||||||
|
|
||||||
|
val response = OkHttp.string(qrCodeUrl, emptyMap(), headers)
|
||||||
|
val json = Json.safeObject(response)
|
||||||
|
|
||||||
|
if (json["errno"].asInt != 0) {
|
||||||
|
return mapOf("error" to "获取登录二维码错误, code: ${json["errno"].asInt}")
|
||||||
|
}
|
||||||
|
|
||||||
|
val sign = json["sign"].asString
|
||||||
|
val imgurl = json["imgurl"].asString
|
||||||
|
val qrCodeImageUrl = "https://$imgurl"
|
||||||
|
|
||||||
|
val qrLoginUrl =
|
||||||
|
"https://wappass.baidu.com/wp/?qrlogin&t=$timestamp" + "&error=0&sign=$sign&cmd=login&lp=pc&tpl=netdisk&uaonly=" + "&client_id=&adapter=3&client=&qrloginfrom=pc&wechat=0&traceid="
|
||||||
|
|
||||||
|
// 返回二维码信息供前端显示
|
||||||
|
val result = mapOf(
|
||||||
|
"qrCodeImageUrl" to qrCodeImageUrl, "qrLoginUrl" to qrLoginUrl, "sign" to sign
|
||||||
|
)
|
||||||
|
|
||||||
|
result
|
||||||
|
} catch (e: Exception) {
|
||||||
|
mapOf("error" to "获取二维码失败: ${e.message}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun checkQRLoginStatus(sign: String): Map<String, Any> {
|
||||||
|
return try {
|
||||||
|
val timestamp = System.currentTimeMillis()
|
||||||
|
val checkUrl =
|
||||||
|
"https://passport.baidu.com/channel/unicast?channel_id=$sign" + "&tpl=netdisk&callback=&apiver=v3&tt=$timestamp&_=$timestamp"
|
||||||
|
|
||||||
|
val response = OkHttp.string(checkUrl, emptyMap(), headers)
|
||||||
|
val cleanResponse = response.trim('(', ' ', '\n', ')')
|
||||||
|
val json = Json.safeObject(cleanResponse)
|
||||||
|
|
||||||
|
if (json["errno"].asInt == 0) {
|
||||||
|
SpiderDebug.log("百度扫码成功")
|
||||||
|
val channelV = json["channel_v"].asString
|
||||||
|
val channelJson = Json.safeObject(channelV)
|
||||||
|
|
||||||
|
if (channelJson["status"].asInt == 0) {
|
||||||
|
val bduss = channelJson["v"].asString
|
||||||
|
|
||||||
|
// 执行登录
|
||||||
|
val loginTimestamp = System.currentTimeMillis()
|
||||||
|
val loginUrl =
|
||||||
|
"https://passport.baidu.com/v3/login/main/qrbdusslogin?" + "v=$loginTimestamp&bduss=$bduss&u=&loginVersion=v4&qrcode=1&tpl=netdisk&apiver=v3" + "&tt=$loginTimestamp&traceid=&callback=bd__cbs__cupstt"
|
||||||
|
|
||||||
|
val loginResponse = OkHttp.get(loginUrl, emptyMap(), headers)
|
||||||
|
val cleanLoginResponse = loginResponse.body.substringAfter("(").substringBeforeLast(")")
|
||||||
|
val loginJson = Json.safeObject(StringEscapeUtils.unescapeHtml4(cleanLoginResponse))
|
||||||
|
|
||||||
|
if (loginJson.has("errInfo") && loginJson["errInfo"].asJsonObject["no"].asString == "0") {
|
||||||
|
// 登录成功,设置cookie
|
||||||
|
SpiderDebug.log("百度登录成功,设置cookie:${bduss}")
|
||||||
|
cookies = "BDUSS=$bduss"
|
||||||
|
cookies = generateCooike(loginResponse.resp["set-cookie"])
|
||||||
|
cache.setUser(User.objectFrom(this.cookies))
|
||||||
|
|
||||||
|
//停止检验线程,关闭弹窗
|
||||||
|
stopService()
|
||||||
|
mapOf("success" to true, "bduss" to bduss)
|
||||||
|
} else {
|
||||||
|
mapOf("error" to "登录失败: $cleanLoginResponse")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
mapOf("status" to channelJson["status"].asInt)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
mapOf("errno" to json["errno"].asInt)
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
mapOf("error" to "检查登录状态失败: ${e.message}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun generateCooike(cookies: List<String>?): String {
|
||||||
|
if (cookies == null || cookies.isEmpty()) {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
val cookieList: MutableList<String?> = ArrayList<String?>()
|
||||||
|
for (cookie in cookies) {
|
||||||
|
cookieList.add(cookie.split(";".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()[0])
|
||||||
|
}
|
||||||
|
return TextUtils.join(";", cookieList)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 显示qrcode
|
||||||
|
*
|
||||||
|
* @param base64Str
|
||||||
|
*/
|
||||||
|
fun showQRCode(bytes: ByteArray) {
|
||||||
|
try {
|
||||||
|
val size = ResUtil.dp2px(240)
|
||||||
|
val params = FrameLayout.LayoutParams(size, size)
|
||||||
|
val image = ImageView(Init.context())
|
||||||
|
image.setScaleType(ImageView.ScaleType.CENTER_CROP)
|
||||||
|
image.setImageBitmap(QRCode.Bytes2Bimap(bytes))
|
||||||
|
val frame = FrameLayout(Init.context())
|
||||||
|
params.gravity = Gravity.CENTER
|
||||||
|
frame.addView(image, params)
|
||||||
|
dialog = AlertDialog.Builder(Init.getActivity()).setView(frame)
|
||||||
|
.setOnCancelListener(DialogInterface.OnCancelListener { dialog: DialogInterface? -> this.dismiss(dialog) })
|
||||||
|
.setOnDismissListener(DialogInterface.OnDismissListener { dialog: DialogInterface? ->
|
||||||
|
this.dismiss(dialog)
|
||||||
|
}).show()
|
||||||
|
dialog!!.getWindow()!!.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
|
||||||
|
Notify.show("请使用百度网盘App扫描二维码")
|
||||||
|
} catch (ignored: java.lang.Exception) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public String getToken() {
|
private fun dismiss() {
|
||||||
User user = cache.getUser();
|
try {
|
||||||
return user.getCookie();
|
dialog?.dismiss()
|
||||||
//return "cGM6MTg4OTY3ODE2MDE6eTM1Tjd1dG58MXxSQ1N8MTc1NDQ2OTgwNzEyOXxzMlN0T1VEV3lOVmF5V3pNbGFfM2tJbVp1ZmlqSHBqaEhTSzVyNHZqVXNRLmlhV3loSUxHNDFkMUI5N1BqXzhWN0dtVWtKLnBTclhpNGpZU1EuTGZWMTV3MVFoZmNpcEVoZkxUV2tvYjB0bkFTYV9RTUhhaHhveWx6YkdmcEhQdjNCS1lrbnp1LkxaWDdKOE40YkNNRjkzT3piNmx2Y0d3TWdVUkl5b18ubVUt";
|
} catch (ignored: java.lang.Exception) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun dismiss(dialog: DialogInterface?) {
|
||||||
|
stopService()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun stopService() {
|
||||||
|
service?.shutdownNow()
|
||||||
|
Init.run(Runnable { this.dismiss() })
|
||||||
|
}
|
||||||
|
|
||||||
|
fun startService(sign: String) {
|
||||||
|
SpiderDebug.log("----start 百度 token service")
|
||||||
|
|
||||||
|
service = Executors.newScheduledThreadPool(1)
|
||||||
|
|
||||||
|
service?.scheduleWithFixedDelay(Runnable {
|
||||||
|
try {
|
||||||
|
SpiderDebug.log("----check百度tatus中")
|
||||||
|
|
||||||
|
checkQRLoginStatus(sign)
|
||||||
|
} catch (e: UnsupportedEncodingException) {
|
||||||
|
throw RuntimeException(e)
|
||||||
|
}
|
||||||
|
}, 3, 3, TimeUnit.SECONDS)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -22,6 +22,7 @@ object BaiduDrive {
|
||||||
"Referer" to "https://pan.baidu.com/"
|
"Referer" to "https://pan.baidu.com/"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
private val saveDirName = "TVBOX_BD"
|
private val saveDirName = "TVBOX_BD"
|
||||||
|
|
||||||
private var cookies = BaiDuYunHandler.get().token
|
private var cookies = BaiDuYunHandler.get().token
|
||||||
|
|
@ -37,6 +38,11 @@ object BaiduDrive {
|
||||||
}
|
}
|
||||||
|
|
||||||
fun processShareLinks(urls: List<String>): Pair<List<String>, List<String>> {
|
fun processShareLinks(urls: List<String>): Pair<List<String>, List<String>> {
|
||||||
|
//首先确保cookie不为空
|
||||||
|
if (cookies.isEmpty()) {
|
||||||
|
BaiDuYunHandler.get().startScan()
|
||||||
|
cookies = BaiDuYunHandler.get().token
|
||||||
|
}
|
||||||
if (urls.isEmpty()) return emptyList<String>() to emptyList()
|
if (urls.isEmpty()) return emptyList<String>() to emptyList()
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -314,6 +320,7 @@ object BaiduDrive {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun parseQueryParams(url: String): Map<String, List<String>> {
|
private fun parseQueryParams(url: String): Map<String, List<String>> {
|
||||||
val query = url.substringAfter(
|
val query = url.substringAfter(
|
||||||
"?"
|
"?"
|
||||||
|
|
@ -768,7 +775,7 @@ object BaiduDrive {
|
||||||
fun playerContent(json: JsonObject, flag: String): String {
|
fun playerContent(json: JsonObject, flag: String): String {
|
||||||
val play = getVideoUrl(json, flag);
|
val play = getVideoUrl(json, flag);
|
||||||
val header = play["header"] as Map<String, String>
|
val header = play["header"] as Map<String, String>
|
||||||
return Result.get().url(buildProxyUrl(play["url"] as String, header) ).octet().header(header).string();
|
return Result.get().url(buildProxyUrl(play["url"] as String, header)).octet().header(header).string();
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getPlayFormatList(): Array<String> {
|
fun getPlayFormatList(): Array<String> {
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ package com.github.catvod.bean.BD;
|
||||||
|
|
||||||
|
|
||||||
import com.github.catvod.api.BaiDuYunHandler;
|
import com.github.catvod.api.BaiDuYunHandler;
|
||||||
import com.github.catvod.api.YunTokenHandler;
|
|
||||||
import com.github.catvod.bean.yun.User;
|
import com.github.catvod.bean.yun.User;
|
||||||
import com.github.catvod.spider.Init;
|
import com.github.catvod.spider.Init;
|
||||||
import com.github.catvod.utils.Path;
|
import com.github.catvod.utils.Path;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,87 @@
|
||||||
|
package com.github.catvod.api;
|
||||||
|
|
||||||
|
import cn.hutool.core.io.FileUtil;
|
||||||
|
import com.github.catvod.utils.Json;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.robolectric.RobolectricTestRunner;
|
||||||
|
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
|
||||||
|
@RunWith(RobolectricTestRunner.class)
|
||||||
|
public class BaiDuYunHandlerTest {
|
||||||
|
|
||||||
|
private BaiDuYunHandler baiDuYunHandler;
|
||||||
|
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
baiDuYunHandler = BaiDuYunHandler.get();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void startScan() throws Exception {
|
||||||
|
// Mock the OkHttp.get method to return a predefined OkResult
|
||||||
|
// Execute the method under test
|
||||||
|
FileUtil.writeBytes(baiDuYunHandler.startScan(), "c://qrcode.png");
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* @Test
|
||||||
|
public void refreshCookie() throws Exception {
|
||||||
|
|
||||||
|
JsonObject obj = Json.safeObject("{\"open.e.189.cn\":{\"OPENINFO\":\"33c28688ef52ce9e3a9ef87388047efbde5e3e2e4c7ef6ef267632468c7dfaf294ff59fa59d34801\",\"pageOp\":\"f73420158c5c010491f1faa4fc91870e\",\"LT\":\"a8900fc0ecae0c59\",\"GUID\":\"b959026ffdf84080ae8567afd9ea4c32\",\"SSON\":\"dc466c8192e3109eaea837c1d136c1fd065253ce1c7d3a66ca1520d7d6d6307b10a1fe65c7becac73b95f24a6e681e654ec4f47c39533ebcc48bb78d6d6e63d1bbf3334e6e97eaa7092d34f87bf1209e256cd4822db68da051a0aeb532d94408c8e50486347fc713813dafc5776a7cfa665ddf96837151232745aa2957fb441d8a79ca7d86f46452060794e6f4b5873ab99ed476629aed2c7b36a44613c92f925dcfd221fce142cd1ecaab667236df697ece293e3ca24030918e5b357bc193118772278748606ade7262bf25ae7527d3c8a059bd48fc08b53b182e61e543a7e9bd1562b50bf80438\"},\"cloud.189.cn\":{\"JSESSIONID\":\"12088774C4B78E632EB944ECA2E6705F\",\"COOKIE_LOGIN_USER\":\"24DA4CBA27A8388982710C2F3D55EFAA84AEE67E9B3EF1B7AC1C565BEEF24C562052CB9B5EAC85E733C10C2704225133CD625407C352ED5D\"}}");
|
||||||
|
baiDuYunHandler.setCookie(obj);
|
||||||
|
baiDuYunHandler.refreshCookie();
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void download() throws Exception {
|
||||||
|
// Mock the OkHttp.get method to return a predefined OkResult
|
||||||
|
// Execute the method under test
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testgetUUID() throws Exception {
|
||||||
|
JsonObject uuid = tianYiHandler.getUUID();
|
||||||
|
System.out.println(uuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testdownloadQRCode() throws Exception {
|
||||||
|
*//*
|
||||||
|
JsonObject uuidInfo = tianYiHandler.getUUID();
|
||||||
|
String uuid = uuidInfo.get("uuid").getAsString();
|
||||||
|
byte[] qrCode = tianYiHandler.downloadQRCode(uuid);
|
||||||
|
FileUtil.writeBytes(qrCode, "c://qrcode.png");
|
||||||
|
|
||||||
|
System.out.println(uuid);*//*
|
||||||
|
|
||||||
|
String url = "https://cloud.189.cn/api/portal/callbackUnify.action?browserId=dff95dced0b03d9d972d920f03ddd05e&redirectURL=https%3A%2F%2Fcloud.189.cn%2Fweb%2Fredirect.html";
|
||||||
|
|
||||||
|
String encode = "https%3A%2F%2Fcloud.189.cn%2Fapi%2Fportal%2FcallbackUnify.action%3FbrowserId%3Ddff95dced0b03d9d972d920f03ddd05e%26redirectURL%3Dhttps%253A%252F%252Fcloud.189.cn%252Fweb%252Fredirect.html";
|
||||||
|
assert URLEncoder.encode(url, "UTF-8").equals(encode);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void loginWithPassword() throws Exception {
|
||||||
|
tianYiHandler.loginWithPassword("18896781601","Lushunming@0526");
|
||||||
|
System.out.println("1111");
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
Binary file not shown.
|
|
@ -1 +1 @@
|
||||||
061c059a302046f02caa7543ad2b5ad4
|
4f3072169892a8d61428ab147dea4766
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"spider": "https://andoridspidermt.netlify.app/jar/custom_spider.jar;md5;061c059a302046f02caa7543ad2b5ad4",
|
"spider": "https://andoridspidermt.netlify.app/jar/custom_spider.jar;md5;4f3072169892a8d61428ab147dea4766",
|
||||||
"lives": [
|
"lives": [
|
||||||
{
|
{
|
||||||
"name": "电视直播",
|
"name": "电视直播",
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue