golang使用阿里云api进行中文分词

笔者刚开始学习go语言,代码有些地方不是很规范而且冗余较多,肯定不是最优的方法,但最终也实现了中文分词,但是不知道什么原因有的时候运行可能会出错,多运行几次即可。

这里我使用的是通过发送http请求来调用

主要在于签名的获取,其他的参数拼接到url上即可

代码参考的是官方签名机制文档下的python代码——签名机制

第一步:
注册阿里云账号,获取AccessKey,这里可参考官方文档API使用方法API使用方法

第二步:
先保存公共参数和api对应参数,具体参数内容可以查看文档(公共参数、API请求参数)
下面的AccessKetId和AccessKeySecret替换成自己的

	AccessKeyId := ""
	AccessKeySecret := ""

	uuid := uuid.NewV4().String()
	sd, _ := time.ParseDuration("-8h")
	timeStamp := time.Now().Add(sd).Format("2006-01-02T15:04:05Z")
	//准备参数
	param := make(map[string]string, 11)
	param["Format"] = "json"
	param["Version"] = "2020-06-29"
	param["AccessKeyId"] = AccessKeyId
	param["SignatureMethod"] = "HMAC-SHA1"
	param["Timestamp"] = timeStamp
	param["SignatureVersion"] = "1.0"
	param["SignatureNonce"] = uuid
	param["ServiceCode"] = "alinlp"
	param["Text"] = "请输入文本"
	param["Action"] = "GetWsChGeneral"
	param["TokenizerId"] = "GENERAL_CHN"

第三步:
对参数按照key的字典序进行排序,存放在keys中

//对参数按照key排序,将key存放在keys中
	keys := make([]string, 0)
	for key := range param {
		keys = append(keys, key)
	}
	sort.Strings(keys)

第四步:
将key和value连接成url的形式,注意这里汉字要改成对应的十六进制编码

//将key-value转化为url的形式
	var url string
	for idx, key := range keys {
		url += (key + "=")
		//汉字编码
		if key == "Text" {
			for _, b := range []byte(param[key]) {
				url += fmt.Sprintf("%%%X", b)
			}
		} else {
			url += param[key]
		}
		if idx != len(keys)-1 {
			url += "&"
		}
	}

第五步:
对得到的url字符串进行url编码,注意这里的编码方式有所不同,可以参考签名机制的文档

	url = url2.QueryEscape(url)
	url = strings.Replace(url, "+", "%20", -1)
	url = strings.Replace(url, "*", "%2A", -1)
	url = strings.Replace(url, "%7E", "%~", -1)
	url = strings.Replace(url, "%3A", "%253A", -1)

第六步:
拼接头部

	url = "GET&%2F&" + url

至此,待签名的字符串已经完成,下面开始计算签名

第七步:
生成密钥

	secret := AccessKeySecret + "&"

第八步:
使用SHA1计算HMAC值并进行base64编码,得到最终签名

	h := hmac2.New(sha1.New, []byte (secret))
	h.Write([]byte(url))
	Signature := base64.StdEncoding.EncodeToString(h.Sum(nil))

至此,签名已得到,接下来拼接最终的url字符串发送request请求
第九步:
将Signature添加到param中,将param的key-value拼接到公有云算法的Endpoint:alinlp.cn-hangzhou.aliyuncs.com后得到最终的url

param["Signature"] = Signature
	Finalurl := "http://alinlp.cn-hangzhou.aliyuncs.com/?"
	for key, value := range param {
		temp := key + "="
		//汉字编码
		if key == "Text" {
			for _, b := range []byte(value) {
				temp += fmt.Sprintf("%%%X", b)
			}
		} else {
			temp += value
		}
		temp += "&"
		Finalurl += temp
	}
	Finalurl = Finalurl[:len(Finalurl)-1]

第十步:
向最终的url发送request请求

	resp, _ := http.Get(Finalurl)
	defer resp.Body.Close()
	body, _ := ioutil.ReadAll(resp.Body)
	fmt.Println(string(body))

执行结果

{“RequestId”:“3B3F45BB-4D3A-5ACA-A667-53DE9C31F768”,“Data”:"{“result”:[{“id”:“0”,“word”:“请”,“tags”:[“基本词-中文”]},{“id”:“1”,“word”:“输入”,“tags”:[“基本词-中文”,“产品类型修饰词”]},{“id”:“2”,“word”:“文本”,“tags”:[“基本词-中文”,“产品类型修饰词”]}],“success”:true}"}

完整代码

package main

import (
	hmac2 "crypto/hmac"
	"crypto/sha1"
	"encoding/base64"
	"fmt"
	uuid "github.com/satori/go.uuid"
	"io/ioutil"
	"net/http"
	url2 "net/url"
	"sort"
	"strings"
	"time"
)

func main() {

	AccessKeyId := "LTAI5tDFcZtdbg8bzYAZyL1S"
	AccessKeySecret := "QDVcavOX07bsLnGviaSTASfYBqfm3o"

	uuid := uuid.NewV4().String()
	sd, _ := time.ParseDuration("-8h")
	timeStamp := time.Now().Add(sd).Format("2006-01-02T15:04:05Z")
	//准备参数
	param := make(map[string]string, 11)
	param["Format"] = "json"
	param["Version"] = "2020-06-29"
	param["AccessKeyId"] = AccessKeyId
	param["SignatureMethod"] = "HMAC-SHA1"
	param["Timestamp"] = timeStamp
	param["SignatureVersion"] = "1.0"
	param["SignatureNonce"] = uuid
	param["ServiceCode"] = "alinlp"
	param["Text"] = "请输入文本"
	param["Action"] = "GetWsChGeneral"
	param["TokenizerId"] = "GENERAL_CHN"

	//对参数按照key排序,将key存放在keys中
	keys := make([]string, 0)
	for key := range param {
		keys = append(keys, key)
	}
	sort.Strings(keys)

	//将key-value转化为url的形式
	var url string
	for idx, key := range keys {
		url += (key + "=")
		//汉字编码
		if key == "Text" {
			for _, b := range []byte(param[key]) {
				url += fmt.Sprintf("%%%X", b)
			}
		} else {
			url += param[key]
		}
		if idx != len(keys)-1 {
			url += "&"
		}
	}
	//fmt.Println(url)
	//url编码
	//然后把编码后的字符串中的加号(+)替换成 %20,星号(*)替换成 %2A,%7E替换回波浪号(~),
	url = url2.QueryEscape(url)
	url = strings.Replace(url, "+", "%20", -1)
	url = strings.Replace(url, "*", "%2A", -1)
	url = strings.Replace(url, "%7E", "%~", -1)
	url = strings.Replace(url, "%3A", "%253A", -1)
	//拼接头
	url = "GET&%2F&" + url
	//fmt.Println(url)

	//拼接SHA1对应的key
	secret := AccessKeySecret + "&"
	//计算SHA1值,并做base64dd
	h := hmac2.New(sha1.New, []byte (secret))
	h.Write([]byte(url))
	Signature := base64.StdEncoding.EncodeToString(h.Sum(nil))

	//将Signature添加到参数中
	param["Signature"] = Signature
	Finalurl := "http://alinlp.cn-hangzhou.aliyuncs.com/?"
	for key, value := range param {
		temp := key + "="
		//汉字编码
		if key == "Text" {
			for _, b := range []byte(value) {
				temp += fmt.Sprintf("%%%X", b)
			}
		} else {
			temp += value
		}
		temp += "&"
		Finalurl += temp
	}
	Finalurl = Finalurl[:len(Finalurl)-1]

	//发送请求
	resp, _ := http.Get(Finalurl)
	defer resp.Body.Close()
	body, _ := ioutil.ReadAll(resp.Body)
	fmt.Println(string(body))
}