本文最后由 森林生灵 于 2020/05/01 18:22:37 编辑
package main import ( "fmt" "io/ioutil" "net/http" "regexp" "strings" ) func main() { // 仅对非会员视频链接有效 url := "https://v.qq.com/x/page/b0945ug7vzo.html" // 先确定 .html 的最早出现的位置,以排除之后 callback 的链接中可能携带的 .html b := strings.Index(url, ".html") // 从确定的 .html 向前找最后一个 / 出现的位置 a := strings.LastIndex(url[:b], "/") // 获取视频 id vid := url[a+1 : b] // 获取视频 json 信息 url = "https://vv.video.qq.com/getinfo?vids=" + vid + "&platform=101001&charge=0&otype=json" resp, err := http.Get(url) if err != nil { fmt.Println(err) return } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { fmt.Println(err) return } // 正则出 json re, err := regexp.Compile("^QZOutputJson=(.*?);$") if err != nil { fmt.Println(err) return } ret := re.FindSubmatch(body) if len(ret) < 2 { fmt.Println("cannot get video info") return } // 获取 fn 与 fvkey // 每次获取的 fn 固定不变 fvkey 会变 var fn, fvkey string // 方法一:查找关键字 // str := string(ret[1]) // ftfn := "\"fn\":\"" // ftfvkey := "\"fvkey\":\"" // // a = strings.LastIndex(str, ftfn) // if a > 0 { // b = strings.Index(str[a+len(ftfn):], "\"") // if b > 0 && len(str) >= a+b { // // a+ 1因为下标为0开始,-1是因为计算长度时将第一位也计算在内,与当前位置重复 // fn = str[a+1+len(ftfn)-1 : a+len(ftfn)+b] // // } // fmt.Println("string()", a, b, len(str), len("\"fn\":\""), fn) // } // // a = strings.LastIndex(str, ftfvkey) // if a > 0 { // b = strings.Index(str[a+len(ftfvkey):], "\"") // if b > 0 && len(str) >= a+b { // // a+ 1因为下标为0开始,-1是因为计算长度时将第一位也计算在内,与当前位置重复 // fvkey = str[a+1+len(ftfvkey)-1 : a+len(ftfvkey)+b] // // } // fmt.Println("string()", a, b, len(str), len("\"fvkey\":\""), fvkey) // } // 方法二:正则匹配 re, err = regexp.Compile(`"fn":"(.*?)"`) if err != nil { fmt.Println(err) return } retfn := re.FindSubmatch(ret[1]) if len(retfn) < 2 { fmt.Println("cannot get the key") return } fn = string(retfn[1]) re, err = regexp.Compile(`"fvkey":"(.*?)"`) if err != nil { fmt.Println(err) return } retfvkey := re.FindSubmatch(ret[1]) if len(retfvkey) < 2 { fmt.Println("cannot get the key") return } fvkey = string(retfvkey[1]) // 方法三:json 解码 emmm... // var info map[string]interface{} // dec := json.NewDecoder(bytes.NewBuffer(ret[1])) // err = dec.Decode(&info) // if err != nil { // fmt.Println(err) // } // // if m, exist := info["vl"]; exist { // if m, ok := m.(map[string]interface{}); ok { // if m, exist := m["vi"]; exist { // // fmt.Printf("%T\n", m) // if m, ok := m.([]interface{}); ok { // if len(m) > 0 { // if m, ok := m[0].(map[string]interface{}); ok { // if m, exist := m["fn"]; exist { // if m, ok := m.(string); ok { // fn = m // } // } // // if m, exist := m["fvkey"]; exist { // if m, ok := m.(string); ok { // fvkey = m // } // } // } // } // } // } // } // } if fn != "" && fvkey != "" { src := "https://ugcws.video.gtimg.com/" + fn + "?vkey=" + fvkey fmt.Println(src) return } fmt.Println("cannot get the key") }
本文标题:golang 解析腾讯视频真实链接
版权声明:本文使用「署名-非商业性使用-相同方式共享」创作共享协议,转载或使用请遵守署名协议。
相关文章
上一篇:gpg 密钥生成与延期