首页 > 其他 > 详细

为知笔记回收站批量还原

时间:2018-06-06 21:03:57      阅读:227      评论:0      收藏:0      [点我收藏+]

背景

不小心删了为知里的笔记,想要还原,然而傻眼了,一次只能还原20个,然而我删了4000多个,手工点这得何年何月啊。
于是查看了为知笔记的请求,写个代码批量发请求,还原笔记。

思路

浏览器打开调试模式,发现了为知笔记获取回收站列表和还原文件的uri为:

  • 回收站列表 /wizks/k/deleted?client_type=web&api_version=10&token=%s&kb_guid=%s&obj_type=document&_=%d
  • 恢复文件 /ks/deleted/recycle/%s?type=document&clientType=web&clientVersion=3.0.0&apiVersion=10&lang=zh-cn

另外发现cookie里还存有token和多个字段,测试了一下,只需要cookie里带着token就可以了

代码

没有什么难点,就直接上代码了,其中guid在地址栏里直接获取到,token得从cookie里取

package main

import (
    "net/http"
    "time"
    "fmt"
    "gopkg.in/resty.v1"
    "github.com/tidwall/gjson"
    "github.com/corpix/uarand"
)

const BaseUrl = "https://note.wiz.cn"

//token  operator_guid  时间戳毫秒
const RecyleUri = "/wizks/k/deleted?client_type=web&api_version=10&token=%s&kb_guid=%s&obj_type=document&_=%d"

//operator_guid
const RestoreUri = "/ks/deleted/recycle/%s?type=document&clientType=web&clientVersion=3.0.0&apiVersion=10&lang=zh-cn"

//请更换为将登录后的参数
var token = ""
var operatorGuid = ""

var retry = 0

func main() {
    cookie := http.Cookie{}
    cookie.Name = "token"
    cookie.Value = token
    cookie.Domain = ".wiz.cn"

    start := time.Now().Unix()

    fmt.Println("task begin")

    requester := resty.SetHostURL(BaseUrl).SetCookie(&cookie).R()

    ch := make(chan int)

    go restore(requester, ch)
ForEnd:
    for {
        select {
        case v := <-ch:
            retry++
            if retry >= 30 || v == 2 {
                break ForEnd
            }
            if v == 1 {
                time.Sleep(time.Second * 3)
                fmt.Println("retry task again")
                requester.SetHeader("User-Agent", uarand.GetRandom())
                go restore(requester, ch)
            }
        }

    }

    fmt.Printf("task completed,use %d seconds.\n", time.Now().Unix()-start)
}

func restore(requester *resty.Request, ch chan int) {

    resp, err := requester.Get(fmt.Sprintf(RecyleUri, token, operatorGuid, time.Now().Nanosecond()/1000000))
    if err != nil || resp.StatusCode() != 200 {
        ch <- 1
        return
    }
    if resp.String() == "[]" {
        ch <- 2
    }

    //数据结构为
    //[{"operator_guid":"","dt_deleted":1507821257000,"deleted_guid":"","deleted_content":""},{...}]
    result := gjson.ParseBytes(resp.Body())
    if result.IsArray() {
        guids := make([]string, 0)
        result.ForEach(func(key, value gjson.Result) bool {
            dGuid := value.Get("deleted_guid").String()
            if dGuid == "" {
                ch <- 1
                return false
            }
            guids = append(guids, dGuid)
            if len(guids) >= 100 {
                res := requestRestore(requester, guids, ch)
                guids = nil
                return res
            }
            return true
        })

        if guids != nil {
            requestRestore(requester, guids, ch)
            guids = nil
        }

    } else {
        fmt.Println(resp.String())
        ch <- 1
    }

}

func requestRestore(requester *resty.Request, guids []string, ch chan int) bool {
    resp, err := requester.SetBody(guids).Post(fmt.Sprintf(RestoreUri, operatorGuid)) //[]string{dGuid}
    if err != nil {
        fmt.Println(err)
        ch <- 1
        return false
    }
    if resp.StatusCode() != 200 || gjson.Get(resp.String(), "returnMessage").String() != "OK" {
        ch <- 1
        return false
    }
    fmt.Printf("a bulk of %d doc restore", len(guids))
    return true
}

吐槽一下,为知笔记恢复,在恢复一页时,居然发了20个请求,然而后端实际上是可以批量恢复的,只需要把这20条的guid一次发过去就可以了。上面的代码就一次发了100个guid。

为知笔记回收站批量还原

原文:https://www.cnblogs.com/xdao/p/golang_wiz.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!