From 3ae7c26a3b0e9d174bb4b796d947dfe1db094620 Mon Sep 17 00:00:00 2001 From: zhiyu1998 Date: Mon, 20 Mar 2023 21:17:15 +0800 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20feat:=20xhs=E8=A7=A3=E6=9E=90?= =?UTF-8?q?=E8=A7=86=E9=A2=91=20&=20xhs=E8=A7=A3=E6=9E=90=E9=80=9F?= =?UTF-8?q?=E5=BA=A6=E6=8F=90=E5=8D=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/tools.js | 121 +++++++++++++++++++++++----------------------- utils/constant.js | 4 +- 2 files changed, 63 insertions(+), 62 deletions(-) diff --git a/apps/tools.js b/apps/tools.js index 936f41a..93a4b63 100644 --- a/apps/tools.js +++ b/apps/tools.js @@ -12,7 +12,7 @@ import HttpProxyAgent from "https-proxy-agent"; import { mkdirsSync } from "../utils/file.js"; import { downloadBFile, getDownloadUrl, mergeFileToMp4, getDynamic } from "../utils/bilibili.js"; import { parseUrl, parseM3u8, downloadM3u8Videos, mergeAcFileToMp4 } from "../utils/acfun.js"; -import { transMap, douyinTypeMap, TEN_THOUSAND } from "../utils/constant.js"; +import { transMap, douyinTypeMap, TEN_THOUSAND, XHS_CK } from "../utils/constant.js"; import { getIdVideo, generateRandomStr } from "../utils/common.js"; import config from "../model/index.js"; @@ -535,69 +535,65 @@ export class tools extends plugin { // 小红书解析 async redbook(e) { + // 解析短号 const msgUrl = /(http:|https:)\/\/(xhslink|xiaohongshu).com\/[A-Za-z\d._?%&+\-=\/#@]*/.exec( e.msg, )[0]; - const url = `https://dlpanda.com/zh-CN/xhs?url=${msgUrl}`; - - await axios - .get(url, { - headers: { - "User-Agent": - "Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Mobile Safari/537.36", - "Content-Type": "application/json", - "Accept-Encoding": "gzip,deflate,compress", - }, - timeout: 10000, - proxy: false, + let id; + if (msgUrl.includes('xhslink')) { + await fetch(msgUrl, { + redirect: 'follow', + }).then(resp => { + const uri = decodeURIComponent(resp.url) + id = /explore\/(\w+)/.exec(uri)[1]; }) - .then(async resp => { - const reg = / { - const addr = `https:${item.split('"')[3]}`; - return axios - .get(addr, { - headers: { - "User-Agent": - "Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Mobile Safari/537.36", - }, - responseType: "stream", - }) - .then(resp => { - const filepath = `${downloadPath}/${/com\/(.*)\?/.exec(addr)[1]}.jpg`; - const writer = fs.createWriteStream(filepath); - resp.data.pipe(writer); - return new Promise((resolve, reject) => { - writer.on("finish", () => resolve(filepath)); - writer.on("error", reject); - }); - }); - }); - let path = []; - const images = await Promise.all(imagesPath).then(paths => { - return paths.map(item => { - path.push(item); - return { - message: segment.image(fs.readFileSync(item)), - nickname: e.sender.card || e.user_id, - user_id: e.user_id, - }; - }); - }); - await this.reply(await Bot.makeForwardMsg(images)); - // 清理文件 - path.forEach(item => { - fs.unlinkSync(item); + } else { + id = /explore\/(\w+)/.exec(msgUrl)[1]; + } + const downloadPath = `${this.defaultPath}${this.e.group_id || this.e.user_id}`; + // 获取信息 + fetch(`https://www.xiaohongshu.com/discovery/item/${id}`, { + headers: { + "user-agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1 Edg/110.0.0.0", + "cookie": Buffer.from(XHS_CK, 'base64').toString('utf-8') + } + }).then(async resp => { + const xhsHtml = await resp.text(); + const reg = /window.__INITIAL_STATE__=(.*?)<\/script>/ + const resJson = xhsHtml.match(reg)[0] + const res = JSON.parse(resJson.match(reg)[1]); + const noteData = res.noteData.data.noteData + const { title, desc, type } = noteData + e.reply(`识别:小红书, ${title}\n${desc}`) + let imgPromise = [] + if (type === 'video') { + const url = noteData.video.url; + this.downloadVideo(url).then(path => { + e.reply(segment.video(path + "/temp.mp4")); + }) + return true; + } else if (type === 'normal') { + noteData.imageList.map (async (item, index) => { + imgPromise.push(this.downloadImg(item.url, downloadPath, index.toString())) + }) + } + let path = []; + const images = await Promise.all(imgPromise).then(paths => { + return paths.map(item => { + path.push(item); + return { + message: segment.image(fs.readFileSync(item)), + nickname: e.sender.card || e.user_id, + user_id: e.user_id, + }; }); }); - + await this.reply(await Bot.makeForwardMsg(images)); + // 清理文件 + path.forEach(item => { + fs.unlinkSync(item); + }); + }) return true; } @@ -743,11 +739,14 @@ export class tools extends plugin { * 下载一张网络图片(自动以url的最后一个为名字) * @param img * @param dir + * @param fileName * @returns {Promise} */ - async downloadImg(img, dir) { - const filename = img.split("/").pop(); - const filepath = `${dir}/${filename}`; + async downloadImg(img, dir, fileName='') { + if (fileName === "") { + fileName = img.split("/").pop(); + } + const filepath = `${dir}/${fileName}`; const writer = fs.createWriteStream(filepath); return axios .get(img, { diff --git a/utils/constant.js b/utils/constant.js index 8e89780..451f3d0 100644 --- a/utils/constant.js +++ b/utils/constant.js @@ -24,4 +24,6 @@ export const douyinTypeMap = { export const TEN_THOUSAND = 10000; -export const CAT_LIMIT = 10; \ No newline at end of file +export const CAT_LIMIT = 10; + +export const XHS_CK = 'eGhzVHJhY2tlcklkPTczODhhYmY2LTI0MDgtNGU5YS04MTUyLTE0MGVhOGY1MTQ5ZjsgeGhzVHJhY2tlcklkLnNpZz1UcGUxTkNaX3B3UkFYdG01SVJmVEs0SWUxM0xBaGZuNmNZU2N4Vi1JYWxFOyBhMT0xODY2ZDkwMDM0NmI2NmppcjMzcGpxZ2MwM3JvcG1mczAydXMxdWNoeDEwMDAwMTM1MDUzOyB3ZWJJZD1mMTNkOGJkYjhiZGM3ZGE0MzY0NjA4NWJjYzQ1MDQ1YTsgZ2lkPXlZS0tmajg4SzA4MnlZS0tmajg4cUo3UzRLREtLVjNGcXFVVjd4Q0FrUzhxRk15OGxVNmlNeTg4OHlxMjgycThmMlk0UzAySjsgZ2lkLnNpZ249YlpzcFFzSUxEUmN5akZLQmN2L1FMWVhkU3lvPTsgd2ViX3Nlc3Npb249MDMwMDM3YTRjMDQyYjE1ZTVjMTg4OTUwOGIyNDRhZDExM2UwNTM7IHhoc1RyYWNrZXI9dXJsPW5vdGVEZXRhaWwmeGhzc2hhcmU9V2VpeGluU2Vzc2lvbjsgeGhzVHJhY2tlci5zaWc9YzdmcDVRclk2SGNvVERhUzluX2N3Z2RCRHh2MFZmWnpSU1NTcnlzbG5lQTsgZXh0cmFfZXhwX2lkcz1oNV8yMzAyMDExX29yaWdpbixoNV8xMjA4X2NsdCxoNV8xMTMwX2NsdCxpb3Nfd3hfbGF1bmNoX29wZW5fYXBwX2V4cCxoNV92aWRlb191aV9leHAzLHd4X2xhdW5jaF9vcGVuX2FwcF9kdXJhdGlvbl9vcmlnaW4scXVlc19jbHQyOyBleHRyYV9leHBfaWRzLnNpZz1DVUdrR3NYT3lBZmpVSXkyVGo3SjN4YmRNakFfSnpoR1JkYWd6cVlkbmJnOyB3ZWJCdWlsZD0xLjEuMjE7IHhzZWNhcHBpZD14aHMtcGMtd2ViOyB3ZWJzZWN0aWdhPTU5ZDNlZjFlNjBjNGFhMzdhN2RmM2MyMzQ2N2JkNDZkN2YxZGEwYjE5MThjZjMzNWVlN2YyZTllNTJhYzA0Y2Y7IHNlY19wb2lzb25faWQ9MTI0OTE1NWQtOWU5ZS00MzkyLTg2NTgtNTA1Yzc0YTUzMTM1'