原教程
原教程图片:
好像快手更新了页面?这一步获取photoid中我没找到教程中的oparetionName:visionVideoDetail,好像更新为:oparetionName:commentListQuery(含有photoid)
然后个人进行修改原教程中的数据(data):
function getKusiShowVideo(id) {
return new Promise((resolve, reject) => {
//这里需要注意的是如果我们把获取的数据直接放到xhr内\n会出现换行的情况
//所以我们需要对这类字符进行转义,把\n改成\\n,这样提交的时候会把\\n转义成\n。
GM_xmlhttpRequest({
url: "https://www.kuaishou.com/graphql",
method: "POST",
data: '{"operationName":"commentListQuery","variables":{"photoId":"'+
id+
'","pcursor":""},"query":"query commentListQuery($photoId: String, $pcursor: String) {\\\n visionCommentList(photoId: $photoId, pcursor: $pcursor) {\\\n commentCount\\\n pcursor\\\n rootComments {\\\n commentId\\\n authorId\\\n authorName\\\n content\\\n headurl\\\n timestamp\\\n likedCount\\\\n realLikedCount\\\\n liked\\\n status\\\n authorLiked\\\n subCommentCount\\\n subCommentsPcursor\\\n subComments {\\\n commentId\\\n authorId\\\n authorName\\\n content\\\n headurl\\\n timestamp\\\n likedCount\\\n realLikedCount\\\n liked\\\n status\\\n authorLiked\\\n replyToUserName\\\n replyTo\\\n __typename\\\n }\\\n __typename\\\n }\\\n __typename\\\n }\\\n}\\\n"}',
headers: {
"Content-type": "application/json",
},
onload: function (xhr) {
console.log(xhr.responseText)
let obj = unsafeWindow.JSON.parse(xhr.responseText);
let res = obj.data.visionProfilePhotoList.feeds;
if (res === null) {
resolve({status:"error"})
}
res.forEach((item) =>{
console.log(item.photo.photoUrl)
downloadurl.push(item.photo.photoUrl);
})
// downloadurl.push(res.photoUrl);
resolve({
status:'success',
// data:res.photoUrl
});
},
});
});
}
但是爆JSON.parse: unexpected character at line 1 column 1 of the JSON data
请问该如何解决?
本人全部代码:
// ==UserScript==
// @name 快手
// @namespace http://tampermonkey.net/
// @version 0.1
// @description try to take over the world!
// @author You
// @match https://www.kuaishou.com/profile/*
// @icon https://www.google.com/s2/favicons?sz=64&domain=kuaishou.com
// @grant unsafeWindow
// @run-at document-start
// @grant GM_setClipboard
// @grant GM_xmlhttpRequest
// @connect *
// ==/UserScript==
let downloadurl = []
let idList = []
function getKusiShowVideo(id) {
return new Promise((resolve, reject) => {
//这里需要注意的是如果我们把获取的数据直接放到xhr内\n会出现换行的情况
//所以我们需要对这类字符进行转义,把\n改成\\n,这样提交的时候会把\\n转义成\n。
GM_xmlhttpRequest({
url: "https://www.kuaishou.com/graphql",
method: "POST",
data: '{"operationName":"commentListQuery","variables":{"photoId":"'+id+'","pcursor":""},"query":"query commentListQuery($photoId: String, $pcursor: String) {\\\n visionCommentList(photoId: $photoId, pcursor: $pcursor) {\\\n commentCount\\\n pcursor\\\n rootComments {\\\n commentId\\\n authorId\\\n authorName\\\n content\\\n headurl\\\n timestamp\\\n likedCount\\\\n realLikedCount\\\\n liked\\\n status\\\n authorLiked\\\n subCommentCount\\\n subCommentsPcursor\\\n subComments {\\\n commentId\\\n authorId\\\n authorName\\\n content\\\n headurl\\\n timestamp\\\n likedCount\\\n realLikedCount\\\n liked\\\n status\\\n authorLiked\\\n replyToUserName\\\n replyTo\\\n __typename\\\n }\\\n __typename\\\n }\\\n __typename\\\n }\\\n}\\\n"}',
headers: {
"Content-type": "application/json",
},
onload: function (xhr) {
console.log(xhr.responseText)
let obj = unsafeWindow.JSON.parse(xhr.responseText);
let res = obj.data.visionProfilePhotoList.feeds;
if (res === null) {
resolve({status:"error"})
}
res.forEach((item) =>{
console.log(item.photo.photoUrl)
downloadurl.push(item.photo.photoUrl);
})
// downloadurl.push(res.photoUrl);
resolve({
status:'success',
// data:res.photoUrl
});
},
});
});
}
// function getKusiShowVideo(id) {
// return new Promise((resolve, reject) => {
// //这里需要注意的是如果我们把获取的数据直接放到xhr内\n会出现换行的情况
// //所以我们需要对这类字符进行转义,把\n改成\\n,这样提交的时候会把\\n转义成\n。
// GM_xmlhttpRequest({
// url: "https://www.kuaishou.com/graphql",
// method: "POST",
// data:
// '{"operationName":"visionVideoDetail","variables":{"photoId":"' +
// id +
// '","page":"detail"},"query":"query visionVideoDetail($photoId: String, $type: String, $page: String, $webPageArea: String) {\\n visionVideoDetail(photoId: $photoId, type: $type, page: $page, webPageArea: $webPageArea) {\\n status\\n type\\n author {\\n id\\n name\\n following\\n headerUrl\\n __typename\\n }\\n photo {\\n id\\n duration\\n caption\\n likeCount\\n realLikeCount\\n coverUrl\\n photoUrl\\n liked\\n timestamp\\n expTag\\n llsid\\n viewCount\\n videoRatio\\n stereoType\\n croppedPhotoUrl\\n manifest {\\n mediaType\\n businessType\\n version\\n adaptationSet {\\n id\\n duration\\n representation {\\n id\\n defaultSelect\\n backupUrl\\n codecs\\n url\\n height\\n width\\n avgBitrate\\n maxBitrate\\n m3u8Slice\\n qualityType\\n qualityLabel\\n frameRate\\n featureP2sp\\n hidden\\n disableAdaptive\\n __typename\\n }\\n __typename\\n }\\n __typename\\n }\\n __typename\\n }\\n tags {\\n type\\n name\\n __typename\\n }\\n commentLimit {\\n canAddComment\\n __typename\\n }\\n llsid\\n danmakuSwitch\\n __typename\\n }\\n}\\n"}',
// headers: {
// "Content-type": "application/json",
// },
// onload: function (xhr) {
// console.log(xhr.responseText)
// let obj = JSON.parse(xhr.responseText);
// let res = obj.data.visionVideoDetail.photo;
// if (res === null) {
// resolve({status:'error'})
// }
// downloadurl.push(res.photoUrl);
// resolve({
// status:'success',
// data:res.photoUrl
// });
// },
// });
// });
// }
console.log("===========================")
let oldFetch = unsafeWindow.fetch;
function hookFetch(...args) {
return new Promise((resolve, reject) => {
oldFetch.call(this, ...args).then((response) => {
// console.log(args)
// console.log(response)
if (
args.length === 2 &&
args[0].indexOf &&
args[0].indexOf("/graphql") !== -1 &&
(args[1].body.indexOf("visionProfilePhotoList") !== -1 )
) {
console.log(args)
console.log(response)
console.log("劫持了json函数");
const oldText = response.text;
const hookText = function () {
console.log("text is run");
return new Promise((resolve, reject) => {
oldText.apply(this, arguments).then((result) => {
console.log("参数:", arguments)
console.log("劫持到了文本", result);
let resJson = unsafeWindow.JSON.parse(result)
resJson.data.visionProfilePhotoList.feeds.forEach((item) => {
idList.push(item.photo.id)
})
// console.log(resJson)
// console.log("劫持到了文本", resJson.data.visionProfilePhotoList.feeds[0].photo.photoUrl);
resolve(result);
});
});
};
// response.text = hookText;
const oldClone = response.clone;
const hookClone = function () {
let result = oldClone.apply(this, arguments);
result.clone = hookClone;
result.text = hookText;
return result;
};
response.clone = hookClone;
}
resolve(response);
});
});
}
unsafeWindow.fetch = hookFetch;
let getVedioBtn = document.createElement("button")
getVedioBtn.innerText = "复制视频"
getVedioBtn.className = "getVedio"
getVedioBtn.style.background = "#757575";
getVedioBtn.style.color = "#fff";
let timer = setInterval(() => {
if (document.querySelector(".follow-button.user-info-follow") !== null) {
let target = document.querySelector(".follow-button.user-info-follow");
//找到了定时器
target.insertAdjacentElement("afterend", getVedioBtn)
clearInterval(timer);
}
}, 1000);
getVedioBtn.addEventListener("click", StatToGetVideo)
async function StatToGetVideo() {
// alert("已开始,不要重复点击!");
let imgnumber = 0;
const downloadurl=[]
console.log(idList)
for (let index = 0; index < idList.length; index++) {
let id = idList[index];
let result = await getKusiShowVideo(id);
if(result.status==='success'){
downloadurl.push(result.data)
}
}
console.log(downloadurl)
GM_setClipboard([...downloadurl].join("\n"));
alert("共成功:"+downloadurl.length+'个');
}