網(wǎng)頁(yè)翻譯 API 簡(jiǎn)介
概念解釋
網(wǎng)頁(yè)翻譯:可對(duì)網(wǎng)頁(yè)html標(biāo)簽自動(dòng)識(shí)別,翻譯所需內(nèi)容。
說(shuō)明
Hi,您好,歡迎使用有道智云網(wǎng)頁(yè)翻譯API接口服務(wù)。
本文檔主要針對(duì)需要集成HTTP API的技術(shù)開(kāi)發(fā)工程師,詳細(xì)描述網(wǎng)頁(yè)翻譯能力相關(guān)的技術(shù)內(nèi)容。
如果您有與我們商務(wù)合作的需求,可以通過(guò)以下方式聯(lián)系我們:
商務(wù)郵箱: AIcloud_Business@corp.youdao.com
如果您對(duì)文檔內(nèi)容有任何疑問(wèn),可以通過(guò)以下幾種方式聯(lián)系我們:
客服QQ:1906538062
智云翻譯技術(shù)交流QQ 1群: 652880659
智云翻譯技術(shù)交流QQ 2群: 669384425
智云翻譯技術(shù)交流QQ 3群: 807539209
智云翻譯技術(shù)交流QQ 4群: 936752411
聯(lián)系郵箱: zhiyun@corp.youdao.com
溫馨提示:
- 本文檔主要針對(duì)開(kāi)發(fā)人員,接入測(cè)試前需要獲取
應(yīng)用ID
和 應(yīng)用密鑰
;如果您還沒(méi)有,請(qǐng)按照新手指南 獲取。 - 平臺(tái)向每個(gè)賬戶贈(zèng)送50元的體驗(yàn)金,供用戶集成前測(cè)試所用,具體資費(fèi)規(guī)則詳見(jiàn) 網(wǎng)頁(yè)翻譯服務(wù)報(bào)價(jià) 。
接口說(shuō)明
網(wǎng)頁(yè)翻譯API接口提供有道的翻譯服務(wù),可對(duì)網(wǎng)頁(yè)html標(biāo)簽自動(dòng)識(shí)別,翻譯所需內(nèi)容,支持多語(yǔ)種進(jìn)行翻譯,詳情參考支持的語(yǔ)種列表。
網(wǎng)頁(yè)翻譯API HTTPS地址:
https://openapi.youdao.com/translate_html
協(xié)議須知
調(diào)用方在集成網(wǎng)頁(yè)翻譯API時(shí),請(qǐng)遵循以下規(guī)則。
規(guī)則 | 描述 |
---|
傳輸方式 | HTTPS |
請(qǐng)求方式 | GET/POST |
字符編碼 | 統(tǒng)一使用UTF-8 編碼 |
請(qǐng)求格式 | 表單 |
響應(yīng)格式 | JSON |
接口調(diào)用參數(shù)
調(diào)用API需要向接口發(fā)送以下字段來(lái)訪問(wèn)服務(wù)。
字段名 | 類型 | 含義 | 必填 | 備注 |
---|
q | text | 待翻譯文本 | True | 必須是UTF-8編碼 |
from | text | 源語(yǔ)言 | True | 參考下方 支持語(yǔ)言 |
to | text | 目標(biāo)語(yǔ)言 | True | 參考下方 支持語(yǔ)言 |
appKey | text | 應(yīng)用ID | True | 可在應(yīng)用管理 查看 |
salt | text | UUID | True | uuid,唯一通用識(shí)別碼 |
sign | text | 簽名 | True | sha256(應(yīng)用ID+input+salt+curtime+應(yīng)用密鑰) |
signType | text | 簽名類型 | True | v3 |
curtime | text | 當(dāng)前UTC時(shí)間戳(秒) | true | TimeStamp |
vocabId | text | 用戶上傳的術(shù)語(yǔ)表 | false | 用戶指定的術(shù)語(yǔ)表ID: out_id,支持英中互譯,更多語(yǔ)種方向請(qǐng)前往控制臺(tái)查詢 |
簽名生成方法如下:
signType=v3;
sign=sha256(應(yīng)用ID
+input
+salt
+curtime
+應(yīng)用密鑰
);
其中,input的計(jì)算方式為:input
=q前10個(gè)字符
+ q長(zhǎng)度
+ q后10個(gè)字符
(當(dāng)q長(zhǎng)度大于20)或 input
=q字符串
(當(dāng)q長(zhǎng)度小于等于20);
注意:
- 接口salt+curtime來(lái)防重放(即一個(gè)請(qǐng)求不可以被請(qǐng)求2次),所以salt最好為UUID。
不同語(yǔ)言獲取時(shí)間戳,請(qǐng)參看此鏈接
如果對(duì)簽名有疑問(wèn),可以參看各語(yǔ)言demo。
用戶術(shù)語(yǔ)表使用
登錄控制臺(tái),選擇網(wǎng)頁(yè)翻譯服務(wù),點(diǎn)擊右側(cè)的術(shù)語(yǔ)表,選擇新建,填寫(xiě)表名稱和語(yǔ)言方向,添加需要的術(shù)語(yǔ)表獲取對(duì)應(yīng)詞表id即可。
輸出結(jié)果
正常返回
字段名 | 含義 |
---|
data | 翻譯結(jié)果 |
errorCode | 錯(cuò)誤碼 |
errorMessage | 成功信息 |
異常返回
字段名 | 含義 |
---|
errorCode | 錯(cuò)誤碼 |
errorMessage | 錯(cuò)誤信息 |
支持語(yǔ)言
下表為各語(yǔ)言對(duì)應(yīng)代碼:
中文名 | 代碼 |
---|
阿拉伯文 | ar |
德文 | de |
英文 | en |
西班牙文 | es |
法文 | fr |
印度尼西亞語(yǔ) | id |
意大利文 | it |
日文 | ja |
韓文 | ko |
荷蘭語(yǔ) | nl |
葡萄牙文 | pt |
俄文 | ru |
泰語(yǔ) | th |
越南語(yǔ) | vi |
中文 | zh-CHS |
中文繁體 | zh-CHT |
注意:若列表語(yǔ)言出現(xiàn)不支持的問(wèn)題,請(qǐng)參文檔下方或者考產(chǎn)品定價(jià)列表語(yǔ)種互譯的限制
以下場(chǎng)景語(yǔ)種間翻譯不支持
源語(yǔ)種中文名 | 代碼 | 目標(biāo)語(yǔ)種中文名 | 代碼 |
---|
德語(yǔ) | de | 印地語(yǔ) | hi |
英語(yǔ) | en | 葡萄牙語(yǔ) | pt |
印地語(yǔ) | hi | 德語(yǔ) | de |
印地語(yǔ) | hi | 荷蘭語(yǔ) | nl |
印地語(yǔ) | hi | 葡萄牙語(yǔ) | pt |
荷蘭語(yǔ) | nl | 印地語(yǔ) | hi |
葡萄牙語(yǔ) | pt | 印地語(yǔ) | hi |
服務(wù)配置
單次查詢最大字符數(shù) | 支持語(yǔ)言 |
---|
100萬(wàn) | 詳見(jiàn)語(yǔ)種表 |
錯(cuò)誤代碼列表
錯(cuò)誤碼 | 含義 |
---|
101 | 缺少必填的參數(shù),首先確保必填參數(shù)齊全,然后確認(rèn)參數(shù)書(shū)寫(xiě)是否正確。 |
102 | 不支持的語(yǔ)言類型 |
103 | 翻譯文本過(guò)長(zhǎng) |
104 | 不支持的API類型 |
105 | 不支持的簽名類型 |
106 | 不支持的響應(yīng)類型 |
107 | 不支持的傳輸加密類型 |
108 | 應(yīng)用ID無(wú)效,注冊(cè)賬號(hào),登錄后臺(tái)創(chuàng)建應(yīng)用并完成綁定,可獲得應(yīng)用ID和應(yīng)用密鑰等信息 |
109 | batchLog格式不正確 |
110 | 無(wú)相關(guān)服務(wù)的有效應(yīng)用,應(yīng)用沒(méi)有綁定服務(wù)應(yīng)用,可以新建服務(wù)應(yīng)用。注:某些服務(wù)的翻譯結(jié)果發(fā)音需要tts服務(wù),需要在控制臺(tái)創(chuàng)建語(yǔ)音合成服務(wù)綁定應(yīng)用后方能使用。 |
111 | 開(kāi)發(fā)者賬號(hào)無(wú)效 |
112 | 請(qǐng)求服務(wù)無(wú)效 |
113 | q不能為空 |
114 | 不支持的圖片傳輸方式 |
116 | strict字段取值無(wú)效,請(qǐng)參考文檔填寫(xiě)正確參數(shù)值 |
201 | 解密失敗,可能為DES,BASE64,URLDecode的錯(cuò)誤 |
202 | 簽名檢驗(yàn)失敗,如果確認(rèn)應(yīng)用ID和應(yīng)用密鑰的正確性,仍返回202,一般是編碼問(wèn)題。請(qǐng)確保翻譯文本 q 為UTF-8編碼. |
203 | 訪問(wèn)IP地址不在可訪問(wèn)IP列表 |
205 | 請(qǐng)求的接口與應(yīng)用的平臺(tái)類型不一致,確保接入方式(Android SDK、IOS SDK、API)與創(chuàng)建的應(yīng)用平臺(tái)類型一致。如有疑問(wèn)請(qǐng)參考入門(mén)指南 |
206 | 因?yàn)闀r(shí)間戳無(wú)效導(dǎo)致簽名校驗(yàn)失敗 |
207 | 重放請(qǐng)求 |
301 | 辭典查詢失敗 |
302 | 翻譯查詢失敗 |
303 | 服務(wù)端的其它異常 |
304 | 會(huì)話閑置太久超時(shí) |
401 | 賬戶已經(jīng)欠費(fèi),請(qǐng)進(jìn)行賬戶充值 |
402 | offlinesdk不可用 |
405 | 鑒權(quán)失敗 |
500 | 翻譯失敗,請(qǐng)參考errorMessage |
411 | 訪問(wèn)頻率受限,請(qǐng)稍后訪問(wèn) |
412 | 長(zhǎng)請(qǐng)求過(guò)于頻繁,請(qǐng)稍后訪問(wèn) |
1001 | 無(wú)效的OCR類型 |
1002 | 不支持的OCR image類型 |
1003 | 不支持的OCR Language類型 |
1004 | 識(shí)別圖片過(guò)大 |
1201 | 圖片base64解密失敗 |
1301 | OCR段落識(shí)別失敗 |
1411 | 訪問(wèn)頻率受限 |
1412 | 超過(guò)最大識(shí)別字節(jié)數(shù) |
2003 | 不支持的語(yǔ)言識(shí)別Language類型 |
2004 | 合成字符過(guò)長(zhǎng) |
2005 | 不支持的音頻文件類型 |
2006 | 不支持的發(fā)音類型 |
2201 | 解密失敗 |
2301 | 服務(wù)的異常 |
2411 | 訪問(wèn)頻率受限,請(qǐng)稍后訪問(wèn) |
2412 | 超過(guò)最大請(qǐng)求字符數(shù) |
3001 | 不支持的語(yǔ)音格式 |
3002 | 不支持的語(yǔ)音采樣率 |
3003 | 不支持的語(yǔ)音聲道 |
3004 | 不支持的語(yǔ)音上傳類型 |
3005 | 不支持的語(yǔ)言類型 |
3006 | 不支持的識(shí)別類型 |
3007 | 識(shí)別音頻文件過(guò)大 |
3008 | 識(shí)別音頻時(shí)長(zhǎng)過(guò)長(zhǎng) |
3009 | 不支持的音頻文件類型 |
3010 | 不支持的發(fā)音類型 |
3201 | 解密失敗 |
3301 | 語(yǔ)音識(shí)別失敗 |
3302 | 語(yǔ)音翻譯失敗 |
3303 | 服務(wù)的異常 |
3411 | 訪問(wèn)頻率受限,請(qǐng)稍后訪問(wèn) |
3412 | 超過(guò)最大請(qǐng)求字符數(shù) |
4001 | 不支持的語(yǔ)音識(shí)別格式 |
4002 | 不支持的語(yǔ)音識(shí)別采樣率 |
4003 | 不支持的語(yǔ)音識(shí)別聲道 |
4004 | 不支持的語(yǔ)音上傳類型 |
4005 | 不支持的語(yǔ)言類型 |
4006 | 識(shí)別音頻文件過(guò)大 |
4007 | 識(shí)別音頻時(shí)長(zhǎng)過(guò)長(zhǎng) |
4201 | 解密失敗 |
4301 | 語(yǔ)音識(shí)別失敗 |
4303 | 服務(wù)的異常 |
4411 | 訪問(wèn)頻率受限,請(qǐng)稍后訪問(wèn) |
4412 | 超過(guò)最大請(qǐng)求時(shí)長(zhǎng) |
5001 | 無(wú)效的OCR類型 |
5002 | 不支持的OCR image類型 |
5003 | 不支持的語(yǔ)言類型 |
5004 | 識(shí)別圖片過(guò)大 |
5005 | 不支持的圖片類型 |
5006 | 文件為空 |
5201 | 解密錯(cuò)誤,圖片base64解密失敗 |
5301 | OCR段落識(shí)別失敗 |
5411 | 訪問(wèn)頻率受限 |
5412 | 超過(guò)最大識(shí)別流量 |
9001 | 不支持的語(yǔ)音格式 |
9002 | 不支持的語(yǔ)音采樣率 |
9003 | 不支持的語(yǔ)音聲道 |
9004 | 不支持的語(yǔ)音上傳類型 |
9005 | 不支持的語(yǔ)音識(shí)別 Language類型 |
9301 | ASR識(shí)別失敗 |
9303 | 服務(wù)器內(nèi)部錯(cuò)誤 |
9411 | 訪問(wèn)頻率受限(超過(guò)最大調(diào)用次數(shù)) |
9412 | 超過(guò)最大處理語(yǔ)音長(zhǎng)度 |
10001 | 無(wú)效的OCR類型 |
10002 | 不支持的OCR image類型 |
10004 | 識(shí)別圖片過(guò)大 |
10201 | 圖片base64解密失敗 |
10301 | OCR段落識(shí)別失敗 |
10411 | 訪問(wèn)頻率受限 |
10412 | 超過(guò)最大識(shí)別流量 |
11001 | 不支持的語(yǔ)音識(shí)別格式 |
11002 | 不支持的語(yǔ)音識(shí)別采樣率 |
11003 | 不支持的語(yǔ)音識(shí)別聲道 |
11004 | 不支持的語(yǔ)音上傳類型 |
11005 | 不支持的語(yǔ)言類型 |
11006 | 識(shí)別音頻文件過(guò)大 |
11007 | 識(shí)別音頻時(shí)長(zhǎng)過(guò)長(zhǎng),最大支持30s |
11201 | 解密失敗 |
11301 | 語(yǔ)音識(shí)別失敗 |
11303 | 服務(wù)的異常 |
11411 | 訪問(wèn)頻率受限,請(qǐng)稍后訪問(wèn) |
11412 | 超過(guò)最大請(qǐng)求時(shí)長(zhǎng) |
12001 | 圖片尺寸過(guò)大 |
12002 | 圖片base64解密失敗 |
12003 | 引擎服務(wù)器返回錯(cuò)誤 |
12004 | 圖片為空 |
12005 | 不支持的識(shí)別圖片類型 |
12006 | 圖片無(wú)匹配結(jié)果 |
13001 | 不支持的角度類型 |
13002 | 不支持的文件類型 |
13003 | 表格識(shí)別圖片過(guò)大 |
13004 | 文件為空 |
13301 | 表格識(shí)別失敗 |
15001 | 需要圖片 |
15002 | 圖片過(guò)大(1M) |
15003 | 服務(wù)調(diào)用失敗 |
17001 | 需要圖片 |
17002 | 圖片過(guò)大(1M) |
17003 | 識(shí)別類型未找到 |
17004 | 不支持的識(shí)別類型 |
17005 | 服務(wù)調(diào)用失敗 |
errorMessage說(shuō)明:
錯(cuò)誤碼 | 含義 |
---|
11 | 不支持的語(yǔ)言方向 |
12 | 輸入的html文本超過(guò)長(zhǎng)度限制 |
14 | 不支持的翻譯內(nèi)容 |
30 | 翻譯失敗 |
31 | 部分翻譯成功 |
常用語(yǔ)言 Demo
Java 示例
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.*;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.*;
public class Translate_htmlV3Demo {
private static Logger logger = LoggerFactory.getLogger(Translate_htmlV3Demo.class);
private static final String YOUDAO_URL = "https://openapi.youdao.com/translate_html";
private static final String APP_KEY = "您的應(yīng)用ID";
private static final String APP_SECRET = "您的應(yīng)用密鑰";
public static void main(String[] args) throws IOException {
Map<String,String> params = new HashMap<String,String>();
String q = "待輸入的文字";
String salt = String.valueOf(System.currentTimeMillis());
String from = "源語(yǔ)言";
String to = "目標(biāo)語(yǔ)言";
params.put("from",from);
params.put("to",to);
params.put("signType", "v3");
String curtime = String.valueOf(System.currentTimeMillis() / 1000);
params.put("curtime", curtime);
String signStr = APP_KEY + truncate(q) + salt + curtime + APP_SECRET;
String sign = getDigest(signStr);
params.put("appKey", APP_KEY);
params.put("q", q);
params.put("salt", salt);
params.put("sign", sign);
/** 處理結(jié)果 */
requestForHttp(YOUDAO_URL,params);
}
public static void requestForHttp(String url,Map<String,String> params) throws IOException {
/** 創(chuàng)建HttpClient */
CloseableHttpClient httpClient = HttpClients.createDefault();
/** httpPost */
HttpPost httpPost = new HttpPost(url);
List<NameValuePair> paramsList = new ArrayList<NameValuePair>();
Iterator<Map.Entry<String,String>> it = params.entrySet().iterator();
while(it.hasNext()){
Map.Entry<String,String> en = it.next();
String key = en.getKey();
String value = en.getValue();
paramsList.add(new BasicNameValuePair(key,value));
}
httpPost.setEntity(new UrlEncodedFormEntity(paramsList,"UTF-8"));
CloseableHttpResponse httpResponse = httpClient.execute(httpPost);
try{
Header[] contentType = httpResponse.getHeaders("Content-Type");
logger.info("Content-Type:" + contentType[0].getValue());
if("audio/mp3".equals(contentType[0].getValue())){
//如果響應(yīng)是wav
HttpEntity httpEntity = httpResponse.getEntity();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
httpResponse.getEntity().writeTo(baos);
byte[] result = baos.toByteArray();
EntityUtils.consume(httpEntity);
if(result != null){//合成成功
String file = "合成的音頻存儲(chǔ)路徑"+System.currentTimeMillis() + ".mp3";
byte2File(result,file);
}
}else{
/** 響應(yīng)不是音頻流,直接顯示結(jié)果 */
HttpEntity httpEntity = httpResponse.getEntity();
String json = EntityUtils.toString(httpEntity,"UTF-8");
EntityUtils.consume(httpEntity);
logger.info(json);
System.out.println(json);
}
}finally {
try{
if(httpResponse!=null){
httpResponse.close();
}
}catch(IOException e){
logger.info("## release resouce error ##" + e);
}
}
}
/**
* 生成加密字段
*/
public static String getDigest(String string) {
if (string == null) {
return null;
}
char hexDigits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
byte[] btInput = string.getBytes();
try {
MessageDigest mdInst = MessageDigest.getInstance("SHA-256");
mdInst.update(btInput);
byte[] md = mdInst.digest();
int j = md.length;
char str[] = new char[j * 2];
int k = 0;
for (byte byte0 : md) {
str[k++] = hexDigits[byte0 >>> 4 & 0xf];
str[k++] = hexDigits[byte0 & 0xf];
}
return new String(str);
} catch (NoSuchAlgorithmException e) {
return null;
}
}
/**
*
* @param result 音頻字節(jié)流
* @param file 存儲(chǔ)路徑
*/
private static void byte2File(byte[] result, String file) {
File audioFile = new File(file);
FileOutputStream fos = null;
try{
fos = new FileOutputStream(audioFile);
fos.write(result);
}catch (Exception e){
logger.info(e.toString());
}finally {
if(fos != null){
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public static String truncate(String q) {
if (q == null) {
return null;
}
int len = q.length();
String result;
return len <= 20 ? q : (q.substring(0, 10) + len + q.substring(len - 10, len));
}
}
python2示例
# -*- coding: utf-8 -*-
import sys
import uuid
import requests
import hashlib
import time
import time
reload(sys)
sys.setdefaultencoding('utf-8')
YOUDAO_URL = 'https://openapi.youdao.com/translate_html'
APP_KEY = '您的應(yīng)用ID'
APP_SECRET = '您的應(yīng)用密鑰'
def encrypt(signStr):
hash_algorithm = hashlib.sha256()
hash_algorithm.update(signStr.encode('utf-8'))
return hash_algorithm.hexdigest()
def truncate(q):
if q is None:
return None
size = len(q)
return q if size <= 20 else q[0:10] + str(size) + q[size - 10:size]
def do_request(data):
headers = {'Content-Type': 'application/x-www-form-urlencoded'}
return requests.post(YOUDAO_URL, data=data, headers=headers)
def connect():
q = "待輸入的文字"
data = {}
data['from'] = '源語(yǔ)言'
data['to'] = '目標(biāo)語(yǔ)言'
data['signType'] = 'v3'
curtime = str(int(time.time()))
data['curtime'] = curtime
salt = str(uuid.uuid1())
signStr = APP_KEY + truncate(q) + salt + curtime + APP_SECRET
sign = encrypt(signStr)
data['appKey'] = APP_KEY
data['q'] = q
data['salt'] = salt
data['sign'] = sign
response = do_request(data)
contentType = response.headers['Content-Type']
if contentType == "audio/mp3":
millis = int(round(time.time() * 1000))
filePath = "合成的音頻存儲(chǔ)路徑" + str(millis) + ".mp3"
fo = open(filePath, 'wb')
fo.write(response.content)
fo.close()
else:
print response.content
if __name__ == '__main__':
connect()
python3示例
# -*- coding: utf-8 -*-
import sys
import uuid
import requests
import hashlib
import time
from importlib import reload
import time
reload(sys)
YOUDAO_URL = 'https://openapi.youdao.com/translate_html'
APP_KEY = '您的應(yīng)用ID'
APP_SECRET = '您的應(yīng)用密鑰'
def encrypt(signStr):
hash_algorithm = hashlib.sha256()
hash_algorithm.update(signStr.encode('utf-8'))
return hash_algorithm.hexdigest()
def truncate(q):
if q is None:
return None
size = len(q)
return q if size <= 20 else q[0:10] + str(size) + q[size - 10:size]
def do_request(data):
headers = {'Content-Type': 'application/x-www-form-urlencoded'}
return requests.post(YOUDAO_URL, data=data, headers=headers)
def connect():
q = "待輸入的文字"
data = {}
data['from'] = '源語(yǔ)言'
data['to'] = '目標(biāo)語(yǔ)言'
data['signType'] = 'v3'
curtime = str(int(time.time()))
data['curtime'] = curtime
salt = str(uuid.uuid1())
signStr = APP_KEY + truncate(q) + salt + curtime + APP_SECRET
sign = encrypt(signStr)
data['appKey'] = APP_KEY
data['q'] = q
data['salt'] = salt
data['sign'] = sign
response = do_request(data)
contentType = response.headers['Content-Type']
if contentType == "audio/mp3":
millis = int(round(time.time() * 1000))
filePath = "合成的音頻存儲(chǔ)路徑" + str(millis) + ".mp3"
fo = open(filePath, 'wb')
fo.write(response.content)
fo.close()
else:
print(response.content)
if __name__ == '__main__':
connect()
php示例
<?php
define("CURL_TIMEOUT", 2000);
define("URL", "https://openapi.youdao.com/translate_html");
define("APP_KEY", "您的應(yīng)用ID"); // 替換為您的應(yīng)用ID
define("SEC_KEY", "您的應(yīng)用密鑰"); // 替換為您的密鑰
function do_request($q)
{
$salt = create_guid();
$args = array(
'q' => $q,
'appKey' => APP_KEY,
'salt' => $salt,
);
$args['from'] = '源語(yǔ)言';
$args['to'] = '目標(biāo)語(yǔ)言';
$args['signType'] = 'v3';
$curtime = strtotime("now");
$args['curtime'] = $curtime;
$signStr = APP_KEY . truncate($q) . $salt . $curtime . SEC_KEY;
$args['sign'] = hash("sha256", $signStr);
$ret = call(URL, $args);
return $ret;
}
// 發(fā)起網(wǎng)絡(luò)請(qǐng)求
function call($url, $args=null, $method="post", $testflag = 0, $timeout = CURL_TIMEOUT, $headers=array())
{
$ret = false;
$i = 0;
while($ret === false)
{
if($i > 1)
break;
if($i > 0)
{
sleep(1);
}
$ret = callOnce($url, $args, $method, false, $timeout, $headers);
$i++;
}
return $ret;
}
function callOnce($url, $args=null, $method="post", $withCookie = false, $timeout = CURL_TIMEOUT, $headers=array())
{
$ch = curl_init();
if($method == "post")
{
$data = convert($args);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_POST, 1);
}
else
{
$data = convert($args);
if($data)
{
if(stripos($url, "?") > 0)
{
$url .= "&$data";
}
else
{
$url .= "?$data";
}
}
}
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
if(!empty($headers))
{
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
}
if($withCookie)
{
curl_setopt($ch, CURLOPT_COOKIEJAR, $_COOKIE);
}
$r = curl_exec($ch);
curl_close($ch);
return $r;
}
function convert(&$args)
{
$data = '';
if (is_array($args))
{
foreach ($args as $key=>$val)
{
if (is_array($val))
{
foreach ($val as $k=>$v)
{
$data .= $key.'['.$k.']='.rawurlencode($v).'&';
}
}
else
{
$data .="$key=".rawurlencode($val)."&";
}
}
return trim($data, "&");
}
return $args;
}
// uuid generator
function create_guid(){
$microTime = microtime();
list($a_dec, $a_sec) = explode(" ", $microTime);
$dec_hex = dechex($a_dec* 1000000);
$sec_hex = dechex($a_sec);
ensure_length($dec_hex, 5);
ensure_length($sec_hex, 6);
$guid = "";
$guid .= $dec_hex;
$guid .= create_guid_section(3);
$guid .= '-';
$guid .= create_guid_section(4);
$guid .= '-';
$guid .= create_guid_section(4);
$guid .= '-';
$guid .= create_guid_section(4);
$guid .= '-';
$guid .= $sec_hex;
$guid .= create_guid_section(6);
return $guid;
}
function create_guid_section($characters){
$return = "";
for($i = 0; $i < $characters; $i++)
{
$return .= dechex(mt_rand(0,15));
}
return $return;
}
function truncate($q) {
$len = abslength($q);
return $len <= 20 ? $q : (mb_substr($q, 0, 10) . $len . mb_substr($q, $len - 10, $len));
}
function abslength($str)
{
if(empty($str)){
return 0;
}
if(function_exists('mb_strlen')){
return mb_strlen($str,'utf-8');
}
else {
preg_match_all("/./u", $str, $ar);
return count($ar[0]);
}
}
function ensure_length(&$string, $length){
$strlen = strlen($string);
if($strlen < $length)
{
$string = str_pad($string, $length, "0");
}
else if($strlen > $length)
{
$string = substr($string, 0, $length);
}
}
// 輸入
$q = "待輸入的文字";
$ret = do_request($q);
print_r($ret);
$ret = json_decode($ret, true);
?>
c#示例
using System;
using System.IO;
using System.Web;
using System.Net;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Threading.Tasks;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Security.Cryptography;
namespace zhiyun_csharp_demo
{
class Translate_htmlV3Demo
{
public static void Main()
{
Dictionary<String, String> dic = new Dictionary<String, String>();
string url = "https://openapi.youdao.com/translate_html";
string q = "待輸入的文字";
string appKey = "您的應(yīng)用ID";
string appSecret = "您的應(yīng)用密鑰";
string salt = DateTime.Now.Millisecond.ToString();
string from = "源語(yǔ)言";
string to = "目標(biāo)語(yǔ)言";
dic.Add("from",from);
dic.Add("to",to);
dic.Add("signType", "v3");
TimeSpan ts = (DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc));
long millis = (long) ts.TotalMilliseconds;
string curtime = Convert.ToString(millis / 1000);
dic.Add("curtime", curtime);
string signStr = appKey + Truncate(q) + salt + curtime + appSecret;;
string sign = ComputeHash(signStr, new SHA256CryptoServiceProvider());
dic.Add("q", System.Web.HttpUtility.UrlEncode(q));
dic.Add("appKey", appKey);
dic.Add("salt", salt);
dic.Add("sign", sign);
Post(url, dic);
}
protected static string ComputeHash(string input, HashAlgorithm algorithm)
{
Byte[] inputBytes = Encoding.UTF8.GetBytes(input);
Byte[] hashedBytes = algorithm.ComputeHash(inputBytes);
return BitConverter.ToString(hashedBytes).Replace("-", "");
}
protected static void Post(string url, Dictionary<String, String> dic)
{
string result = "";
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
req.Method = "POST";
req.ContentType = "application/x-www-form-urlencoded";
StringBuilder builder = new StringBuilder();
int i = 0;
foreach (var item in dic)
{
if (i > 0)
builder.Append("&");
builder.AppendFormat("{0}={1}", item.Key, item.Value);
i++;
}
byte[] data = Encoding.UTF8.GetBytes(builder.ToString());
req.ContentLength = data.Length;
using (Stream reqStream = req.GetRequestStream())
{
reqStream.Write(data, 0, data.Length);
reqStream.Close();
}
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
if (resp.ContentType.ToLower().Equals("audio/mp3"))
{
SaveBinaryFile(resp, "合成的音頻存儲(chǔ)路徑");
}
else {
Stream stream = resp.GetResponseStream();
using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))
{
result = reader.ReadToEnd();
}
Console.WriteLine(result);
}
}
protected static string Truncate(string q)
{
if (q == null)
{
return null;
}
int len = q.Length;
return len <= 20 ? q : (q.Substring(0, 10) + len + q.Substring(len - 10, 10));
}
private static bool SaveBinaryFile(WebResponse response, string FileName)
{
string FilePath = FileName + DateTime.Now.Millisecond.ToString() + ".mp3";
bool Value = true;
byte[] buffer = new byte[1024];
try
{
if (File.Exists(FilePath))
File.Delete(FilePath);
Stream outStream = System.IO.File.Create(FilePath);
Stream inStream = response.GetResponseStream();
int l;
do
{
l = inStream.Read(buffer, 0, buffer.Length);
if (l > 0)
outStream.Write(buffer, 0, l);
}
while (l > 0);
outStream.Close();
inStream.Close();
}
catch
{
Value = false;
}
return Value;
}
}
}