梦泽宇 发表于 2023-10-11 13:09:01

快手视频获取求助

[原教程](https://learn.scriptcat.org/docs/practice/%E5%AE%9E%E6%88%98Fetch%E5%8A%AB%E6%8C%81%E5%BF%AB%E6%89%8B%E6%89%B9%E9%87%8F%E8%AF%BB%E5%8F%96/)


***

原教程图片:
!(data/attachment/forum/202310/11/125524zh6xygvzuju2c222.png)
好像快手更新了页面?这一步获取photoid中我没找到教程中的oparetionName:**visionVideoDetail**,好像更新为:oparetionName:**commentListQuery**(含有photoid)
!(data/attachment/forum/202310/11/130005deojnoqjhkwhzend.png)
然后个人进行修改原教程中的数据(data):
```javascript~~~~
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) {\\\nvisionCommentList(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`
!(data/attachment/forum/202310/11/130344vaqtftf1jffj5fft.png)


***

请问该如何解决?

***


本人全部代码:
```javascript
// ==UserScript==
// @name         快手
// @namespace    http://tampermonkey.net/
// @version      0.1
// @descriptiontry 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) {\\\nvisionCommentList(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) {\\nvisionVideoDetail(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.indexOf &&
      args.indexOf("/graphql") !== -1 &&
      (args.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.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;
    let result = await getKusiShowVideo(id);
    if(result.status==='success'){
      downloadurl.push(result.data)
    }
}
    console.log(downloadurl)
GM_setClipboard([...downloadurl].join("\n"));
alert("共成功:"+downloadurl.length+'个');
}

```

李恒道 发表于 2023-10-11 15:32:26

![图片.png](data/attachment/forum/202310/11/153210tlopbjrhllcnc3hr.png)
新版本已经不需要发送数据来获取源视频文件地址了

李恒道 发表于 2023-10-11 13:09:02

梦泽宇 发表于 2023-10-11 16:31
噢噢,问下道哥,你这个是具体哪个请求,我怎么没找到

现在点击新视频好像没有视频地址的获取的接口了
直接根据列表获取视频地址单独显示

梦泽宇 发表于 2023-10-11 16:31:31

李恒道 发表于 2023-10-11 15:32
![图片.png](data/attachment/forum/202310/11/153210tlopbjrhllcnc3hr.png)
新版本已经不需要发送数据 ...

噢噢,问下道哥,你这个是具体哪个请求,我怎么没找到
页: [1]
查看完整版本: 快手视频获取求助