百度雲如今開放了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屬性,將其解析到本身的百度雲服務器。緩存