百度雲開放referer api接口 ,能夠獲取百度關鍵詞

百度雲如今開放了referer api功能,能夠經過 百度refer中的eqid參數來獲取百度關鍵詞。html

詳見:https://cloud.baidu.com/doc/RefererAPI/ProductDescription.htmlpython

此接口爲付費接口,並且目前只能在百度雲(北京)的環境內調用。也就是說,想調用此接口,必需要有一臺百度雲北京區域的服務器,能夠在百度雲服務器上搭建代理服務,來實現遠程調用。golang

注:json

  1. 只有企業認證的帳戶才能調用此接口,我的帳戶沒法調用。
  2. 能夠考慮使用緩存來減小接口請求次數,可是關鍵詞和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屬性,將其解析到本身的百度雲服務器。緩存

相關文章
相關標籤/搜索