百度云如今开放了referer api功能,能够经过 百度refer中的eqid参数来获取百度关键词。html
详见:https://cloud.baidu.com/doc/RefererAPI/ProductDescription.htmlpython
此接口为付费接口,并且目前只能在百度云(北京)的环境内调用。也就是说,想调用此接口,必需要有一台百度云北京区域的服务器,能够在百度云服务器上搭建代理服务,来实现远程调用。golang
注:json
- 只有企业认证的帐户才能调用此接口,我的帐户没法调用。
- 能够考虑使用缓存来减小接口请求次数,可是关键词和eqid是一对多的关系,在不一样的时间搜索同一个关键词,eqid是会变化的。因此,缓存做用有限。
官方目前只给出了python版本的代码示例,下面是我参照官方python示例写出的golang版本的测试代码:api
package main import ( "crypto/hmac" "crypto/sha256" "encoding/hex" "encoding/json" "errors" "fmt" "io/ioutil" "net/http" "net/url" "strings" "time" ) func getAuth(accessKey, accessSecret, utcTimeStr, urlstr, method string) (string, error) { urlParseRet, err := url.Parse(urlstr) if err != nil { return "", err } host := urlParseRet.Host path := urlParseRet.Path version := "1" expirationSeconds := "1800" signatureHeaders := "host" val := fmt.Sprintf("bce-auth-v%s/%s/%s/%s", version, accessKey, utcTimeStr, expirationSeconds) key := []byte(accessSecret) h := hmac.New(sha256.New, key) _, err = h.Write([]byte(val)) if err != nil { return "", errors.New("writing key error:" + err.Error()) } signingKey := hex.EncodeToString(h.Sum(nil)) canonicalURI, err := url.PathUnescape(path) if err != nil { return "", errors.New("unescape path failed:" + err.Error()) } canonicalHeaders := fmt.Sprintf("host:%s", strings.Trim(host, " ")) canonicalRequest := fmt.Sprintf("%s\n%s\n\n%s", strings.ToUpper(method), canonicalURI, canonicalHeaders) key = []byte(signingKey) h = hmac.New(sha256.New, key) _, err = h.Write([]byte(canonicalRequest)) if err != nil { return "", errors.New("writing signature error:" + err.Error()) } signature := hex.EncodeToString(h.Sum(nil)) authorization := fmt.Sprintf("bce-auth-v%s/%s/%s/%s/%s/%s", version, accessKey, utcTimeStr, expirationSeconds, signatureHeaders, signature) return authorization, nil } // 将时间戳(精确到秒)0转换为时间字符串 func DateTime(timestamp int64) string { var lctime = time.Unix(timestamp, 0) timelayout := "2006-01-02T15:04:05Z" lca, err := time.LoadLocation("") if err != nil { panic(err) } var ltime = lctime.In(lca).Format(timelayout) return ltime } func GetKeywordByEqid(eqid string) string { accessKey := "xxxx" accessSecret := "xxxx" reqUrl := "http://referer.bj.baidubce.com/v1/eqid" + "/" + eqid method := "GET" utcTime := time.Now().Unix() utcTimeStr := DateTime(utcTime) auth, _ := getAuth(accessKey, accessSecret, utcTimeStr, reqUrl, method) // 发送http请求 client := &http.Client{} //提交请求 reqest, err := http.NewRequest("GET", reqUrl, nil) //增长header选项 reqest.Header.Add("accept-encoding", "gzip, deflate") reqest.Header.Add("host", "referer.bj.baidubce.com") reqest.Header.Add("content-type", "application/json") reqest.Header.Add("x-bce-date", utcTimeStr) reqest.Header.Add("authorization", auth) reqest.Header.Add("accept", "*/*") if err != nil { panic(err) } begin := time.Now() //处理返回结果 response, err := client.Do(reqest) if err != nil { panic(err) } defer response.Body.Close() body, err := ioutil.ReadAll(response.Body) if err != nil { panic(err) } result := string(body) fmt.Println(result) resultDecode, err := url.QueryUnescape(result) if err != nil { panic(err) } end := time.Now() td := end.Sub(begin) fmt.Println("timeUsed:\t", td) return resultDecode } func main() { result := GetKeywordByEqid("d6ebbb990001e54a000000065b7989ad") resultMap := make(map[string]string) err := json.Unmarshal([]byte(result), &resultMap) if err != nil { panic(err) } keyword := "" if _, ok := resultMap["wd"]; ok { keyword = resultMap["wd"] } fmt.Println(keyword) }
须要注意的是:referer.bj.baidubce.com这个域名,在公网是没有dns解析的,只在北京的百度云内有解析,可是在加密的时候,会对请求的host进行加密,因此咱们须要在本身的服务器上,把这个域名解析到本身购买的百度云服务器上,再将其代理到这个域名。若是使用curl,能够直接经过curlopt_connect_to属性,将其解析到本身的百度云服务器。缓存