🎈 pref: V1.5.9 优化了皮皮虾描述

1. 优化了皮皮虾的描述,描述的需求来自群友柒
2. 对通用解析进行大幅度优化,提升了插件的通用性、健壮性,并且增加了新的第三方接口。
3. 修正x的部分问题(通用解析导致)
This commit is contained in:
zhiyu1998 2024-03-17 21:54:41 +08:00
parent c528634c39
commit c7d271e963
4 changed files with 151 additions and 70 deletions

View File

@ -582,7 +582,7 @@ export class tools extends plugin {
const reg = /https?:\/\/x.com\/[0-9-a-zA-Z_]{1,20}\/status\/([0-9]*)/;
const twitterUrl = reg.exec(e.msg)[0];
// 提取视频
const videoUrl = GENERAL_REQ_LINK.replace("{}", twitterUrl);
const videoUrl = GENERAL_REQ_LINK.link.replace("{}", twitterUrl);
e.reply("识别:小蓝鸟");
axios.get(videoUrl, {
headers: {
@ -982,33 +982,12 @@ export class tools extends plugin {
* @return {Promise<void>}
*/
async general(e) {
const linkAdapter = new GeneralLinkAdapter(e.msg);
const adapter = await linkAdapter.build();
logger.mark(adapter.link)
e.reply(`识别:${adapter.name}`);
// 发送GET请求
axios.get(adapter.link, {
headers: {
'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',
'Accept-Language': 'zh-CN,zh;q=0.9',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive',
'Pragma': 'no-cache',
'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 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36',
},
timeout: 10000 // 设置超时时间
}).then(resp => {
// 图片https://kph8gvfz.m.chenzhongtech.com/fw/photo/3x45s52s9wchwwm
if (resp.data.data?.imageUrl) {
const imageUrl = resp.data.data.imageUrl;
const images = imageUrl.map(item => {
try {
const adapter = await GeneralLinkAdapter.create(e.msg);
e.reply(`识别:${ adapter.name }${ adapter.desc ? `, ${ adapter.desc }` : '' }`);
logger.mark(adapter);
if (adapter.images && adapter.images.length > 0) {
const images = adapter.images.map(item => {
return {
message: segment.image(item),
nickname: this.e.sender.card || this.e.user_id,
@ -1016,14 +995,20 @@ export class tools extends plugin {
}
})
e.reply(Bot.makeForwardMsg(images));
} else {
} else if (adapter.video && adapter.video !== '') {
// 视频https://www.kuaishou.com/short-video/3xhjgcmir24m4nm
const url = resp.data.data.url;
const url = adapter.video;
this.downloadVideo(url).then(path => {
e.reply(segment.video(path + "/temp.mp4"));
});
} else {
e.reply("解析失败:无法获取到资源");
}
});
} catch (err) {
logger.error("解析失败 ", err);
return true
}
return true
}
/**

View File

@ -1,5 +1,5 @@
- {
version: 1.5.8,
version: 1.5.9,
data:
[
优化<span class="cmd">哔哩哔哩简介</span>功能,

View File

@ -81,7 +81,14 @@ export const XHS_REQ_LINK = "https://www.xiaohongshu.com/explore/"
* 🍉 的请求链接
* @type {string}
*/
export const GENERAL_REQ_LINK = "http://47.99.158.118/video-crack/v2/parse?content={}"
export const GENERAL_REQ_LINK = {
link: "http://47.99.158.118/video-crack/v2/parse?content={}",
sign: 1
}
export const GENERAL_REQ_LINK_2 = {
link: "https://acid.jiuzige.com.cn/web/index/analysis?url={}",
sign: 2
}
/**
* 获取网易云歌曲下载链接

View File

@ -1,24 +1,41 @@
import { GENERAL_REQ_LINK } from "../constants/tools.js";
import {
GENERAL_REQ_LINK,
GENERAL_REQ_LINK_2
} from "../constants/tools.js";
/**
* 第三方接口适配器用户大面积覆盖解析视频的内容
*/
class GeneralLinkAdapter {
#url;
constructor(link) {
console.log("============",link)
if (/share.xiaochuankeji.cn/.test(link)) {
this.#url = this.zuiyou(link);
} else if (/kuaishou.com/.test(link)) {
this.#url = this.ks(link);
} else if (/ixigua.com/.test(link)) {
this.#url = this.xigua(link);
} else if (/h5.pipix.com/.test(link)) {
this.#url = this.pipixia(link);
} else if (/h5.pipigx.com/.test(link)) {
this.#url = this.pipigx(link);
}
constructor() {
}
/**
* 暂时用这个来处理短链接
* @param url
* @param includeRedirect
* @returns {Promise<string|Response>}
*/
async fetchUrl(url, includeRedirect = false) {
let response = await fetch(url, {
headers: {
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36',
}
});
return includeRedirect ? response.url : response;
}
/**
* 辅助函数该函数接收原始链接和需要插入的视频请求链接videoReq然后返回一个新的链接对象
* @param originalLink
* @param videoReq
* @returns {*}
*/
createReqLink(originalLink, videoReq) {
let reqLink = { ...originalLink };
reqLink.link = reqLink.link.replace("{}", videoReq);
return reqLink;
}
async ks(link) {
@ -28,13 +45,7 @@ class GeneralLinkAdapter {
let msg = /(?:https?:\/\/)?(www|v)\.kuaishou\.com\/[A-Za-z\d._?%&+\-=\/#]*/g.exec(link)[0];
// 跳转短号
if (msg.includes("v.kuaishou")) {
await fetch(msg, {
headers: {
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36',
}
}).then(resp => {
msg = resp.url;
})
msg = await this.fetchUrl(msg, true);
}
let video_id;
if (msg.includes('/fw/photo/')) {
@ -42,19 +53,21 @@ class GeneralLinkAdapter {
} else if (msg.includes("short-video")) {
video_id = msg.match(/short-video\/([^/?]+)/)[1];
} else {
throw "无法提取快手的信息,请重试或者换一个视频!";
throw Error("无法提取快手的信息,请重试或者换一个视频!");
}
const reqLink = this.createReqLink(GENERAL_REQ_LINK, `https://www.kuaishou.com/short-video/${video_id}`);
// 提取视频
return {
name: "快手",
link: GENERAL_REQ_LINK.replace("{}", `https://www.kuaishou.com/short-video/${ video_id }`)
reqLink
};
}
async zuiyou(link) {
// #最右#分享一条有趣的内容给你,不好看算我输。请戳链接>>https://share.xiaochuankeji.cn/hybrid/share/post?pid=365367131&zy_to=applink&share_count=1&m=dc114ccc8e55492642f6a702b510c1f6&d=9e18ca2dace030af656baea96321e0ea353fe5c46097a7f3962b93f995641e962796dd5faa231feea5531ac65547045f&app=zuiyou&recommend=r0&name=n0&title_type=t0
const msg = /(?:https?:\/\/)?(share|share.xiaochuankeji)\.cn\/[A-Za-z\d._?%&+\-=\/#]*/.exec(link)[0];
return {name: "最右", link: GENERAL_REQ_LINK.replace("{}", msg)};
const reqLink = this.createReqLink(GENERAL_REQ_LINK, msg);
return { name: "最右", reqLink };
}
async xigua(link) {
@ -64,32 +77,108 @@ class GeneralLinkAdapter {
let msg = /(?:https?:\/\/)?(www|v|m)\.ixigua\.com\/[A-Za-z\d._?%&+\-=\/#]*/g.exec(link)[0];
// 跳转短号
if (msg.includes("v.ixigua")) {
await fetch(msg, {
headers: {
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36',
}
}).then(resp => {
msg = resp.url;
})
msg = await this.fetchUrl(msg, true);
}
const id = /ixigua\.com\/(\d+)/.exec(msg)[1] || /\/video\/(\d+)/.exec(msg)[1];
const videoReq = `https://www.ixigua.com/${ id }`;
return {name: "西瓜", link: GENERAL_REQ_LINK.replace("{}", videoReq)};
const reqLink = this.createReqLink(GENERAL_REQ_LINK, videoReq);
return { name: "西瓜", reqLink };
}
async pipixia(link) {
const msg = /https:\/\/h5\.pipix\.com\/s\/[A-Za-z0-9]+/.exec(link)?.[0];
return {name: "皮皮虾", link: GENERAL_REQ_LINK.replace("{}", msg)};
// 这里必须使用{ ...GENERAL_REQ_LINK_2 }赋值,不然就是对象的引用赋值,会造成全局数据问题!
const reqLink = this.createReqLink(GENERAL_REQ_LINK_2, msg);
return { name: "皮皮虾", reqLink };
}
async pipigx(link) {
const msg = /https:\/\/h5\.pipigx\.com\/pp\/post\/[A-Za-z0-9]+/.exec(link)?.[0];
return {name: "皮皮搞笑", link: GENERAL_REQ_LINK.replace("{}", msg)};
const reqLink = this.createReqLink(GENERAL_REQ_LINK, msg);
return { name: "皮皮搞笑", reqLink };
}
async build() {
return this.#url;
/**
* 初始化通用适配器
* @param link 通用链接
* @returns {Promise<*>}
*/
async init(link) {
logger.mark("[R插件][通用解析]", link)
const handlers = new Map([
[/share.xiaochuankeji.cn/, this.zuiyou.bind(this)],
[/kuaishou.com/, this.ks.bind(this)],
[/ixigua.com/, this.xigua.bind(this)],
[/h5.pipix.com/, this.pipixia.bind(this)],
[/h5.pipigx.com/, this.pipigx.bind(this)],
]);
for (let [regex, handler] of handlers) {
if (regex.test(link)) {
return handler(link);
}
}
}
/**
* 通用解析适配器将其他的第三方接口转换为统一的接口
* @param adapter 通用解析适配器
* @param sign 通用解析标识12 在适配器的reqLink中
* @returns {Promise<void>}
*/
async resolve(adapter, sign) {
// 发送GET请求
return fetch(adapter.reqLink.link, {
headers: {
'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',
'Accept-Language': 'zh-CN,zh;q=0.9',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive',
'Pragma': 'no-cache',
'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 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36',
},
timeout: 10000
}).then(async resp => {
const data = await resp.json();
if (sign === 1) {
// @link GENERAL_REQ_LINK
return {
name: adapter.name,
images: data.data?.imageUrl,
video: data.data?.url,
}
} else if (sign === 2) {
// @link GENERAL_REQ_LINK_2
return {
name: adapter.name,
images: data.data?.images,
video: data.data?.videoUrl,
desc: data.data?.desc
}
} else {
throw Error("[R插件][通用解析]错误Sign标识");
}
})
}
/**
* 通过工厂方式创建一个通用解析的JSON对象
* @param link
* @returns {Promise<*>}
*/
static async create(link) {
// 先正则匹配到函数进行出策略处理
const adapter = await new GeneralLinkAdapter();
const adapterHandler = await adapter.init(link);
// 对处理完的信息进行通用解析
return adapter.resolve(adapterHandler, adapterHandler.reqLink.sign);
}
}