昨天分享了抖音图集短视频云函数去水印解析的开发实践,今天来说说快手的图集短视频解析,其实原理都差不多,哦,对了昨天以这些案例开发的小程序还在审核就没有分享,今天分享出来给大家看看效果,我没有做下载处理,所以短视频下载的话需要复制链接到其他点下载,不过这都不是啥难点。主要是实现去水印的目的就行,仅做演示。柠檬去水印
首先还是获取一个快手短视频或者图集的链接,演示如下:
ruby
https://v.kuaishou.com/dlyk1
然后传到后端,后端会获取到其重定向到地址,但是考虑到有可能会重定向几次,所以做了一些处理,代码如下:
javascript
async getFinalRedirectUrl(url, maxRedirects = 5) {
let currentUrl = url;
let redirectCount = 0;
while (redirectCount < maxRedirects) {
try {
const response = await this.curl(currentUrl, {
method: "GET",
dataType: "text",
followRedirect: false,
});
if (response.headers.location) {
currentUrl = new URL(response.headers.location, currentUrl).href;
console.log(`重定向 ${redirectCount + 1}: ${currentUrl}`);
redirectCount++;
} else {
// 没有更多重定向,返回当前URL
return currentUrl;
}
} catch (error) {
console.error(`重定向过程中出错 (${currentUrl}):`, error);
throw error;
}
}
console.warn(`达到最大重定向次数 (${maxRedirects})`);
return currentUrl;
}
获取到的原地址应该如下:
ruby
https://v.m.chenzhongtech.com/fw/photo/3xnh6zqupyhfm5e?cc=share_copylink&followRefer=151&shareMethod=TOKEN&docId=9&kpn=KUAISHOU&subBiz=BROWSE_SLIDE_PHOTO&photoId=3xnh6zqupyhfm5e&shareId=18116220443971&shareToken=X44fHQnInAjW1py&shareResourceType=PHOTO_OTHER&userId=3xw7it7sxf6k7pe&shareType=1&et=1_i%2F2007717946053474769_scn0&shareMode=APP&efid=0&originShareId=18116220443971&appType=1&shareObjectId=5241064204127827041&shareUrlOpened=0×tamp=1729591920122
研究域名可以得到其中的ID,也就是链接中的3xnh6zqupyhfm5e,然后进行下一步,构造移动版网页URL,如下:
makefile
const 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",
Accept: "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
"Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8",
};
const mobileUrl = `https://c.kuaishou.com/fw/photo/${photoId}`;
// 发送请求获取信息
const response = await this.curl(mobileUrl, {
headers: this.headers,
dataType: "text",
});
console.log("响应数据:", response)
最后就是得到响应后的处理了。
typescript
parseContentInfo(html) {
const jsonMatch = html.match(
/<script>window\.INIT_STATE = (.*?)<\/script>/
);
if (!jsonMatch) return null;
try {
const initState = JSON.parse(jsonMatch[1]);
// 找到包含内容信息的键
const contentInfoKey = Object.keys(initState).find(
(key) => key.startsWith("tusjoh") && (initState[key].photo || initState[key].atlas)
);
console.log("内容信息键:", contentInfoKey);
if (!contentInfoKey) {
console.error("无法找到内容信息");
return null;
}
const contentInfo = initState[contentInfoKey];
console.log("内容信息:", contentInfo);
const isAtlas = !!contentInfo.atlas;
const photoInfo = contentInfo.photo;
const atlasInfo = contentInfo.atlas;
const baseInfo = {
type: isAtlas ? "image_set" : "video",
author: photoInfo.userName,
uid: photoInfo.userId,
avatar: photoInfo.headUrls[0].url,
like_count: photoInfo.likeCount,
comment_count: photoInfo.commentCount,
time: photoInfo.timestamp,
title: photoInfo.caption,
cover: photoInfo.coverUrls[0].url,
view_count: photoInfo.viewCount,
share_count: photoInfo.shareCount || 0,
platform: "kuaishou",
};
if (isAtlas) {
baseInfo.images = atlasInfo.list.map((path, index) => ({
url: `https://${atlasInfo.cdn[0]}${path}`,
width: atlasInfo.size[index].w,
height: atlasInfo.size[index].h,
}));
} else {
baseInfo.url = photoInfo.mainMvUrls[0].url;
baseInfo.duration = photoInfo.duration;
}
return baseInfo;
} catch (error) {
console.error("解析JSON数据时出错:", error);
return null;
}
}
快手的数据有一个点不懂,他有一个很长的键,所以我们需要找到它,然后在进行处理,代码中的contentInfoKey就是起到这个作用,不过以后会不会变就不知道了,主要是方法,变了以后再改就行了。
javascript
// 找到包含内容信息的键
const contentInfoKey = Object.keys(initState).find(
(key) => key.startsWith("tusjoh") && (initState[key].photo || initState[key].atlas)
);
以上就是今天的内容了,有什么不懂的留言问就行。