1. 程式人生 > >為知筆記回收站批量還原

為知筆記回收站批量還原

時間 pack result 發現 domain sco TP select guid

背景

不小心刪了為知裏的筆記,想要還原,然而傻眼了,一次只能還原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。

為知筆記回收站批量還原