打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
让Python使用Bing翻译API V2 | 查问题

 

 

最近要整点自动翻译的东东,发现最亲民的Google的翻译API关闭了。那么摆在码农的面前大概也只有2条路,

一是,直接使用web版本的的google翻译,然后分析URL,和结果得到翻译结果。然后直接调用,网上好像已经有兄弟们这样干了。

二是,投奔微软的阵营,使用Bing的API,

犹豫我要翻译的东东好像在bing这儿的翻译效果还可以,另外也训练一下自己的Python能力,做点开源的事情。打算写个Python使用Bing的API代码测试一下。

Bing的翻译API也不是绝对免费,每个月可以翻译2M的字符的数据。这个当然不多,但一般人也够用了。(纯文本的圣经4M多)。超出后如果要再使用也必须付费,

费用好像是2M 40美刀。

另外Bing的API有一些有特色的地方,比如你可以在里面增加一些自己的翻译,帮助修正你的翻译结果,另外其还有语音能力。可以将你输入的语音转换为wav或者mp3文件。上流。

网上有些兄弟写过Bing的API,但是大部分是是对于V1的版本的,V2版本改了验证方式

现在微软已经使用了新的验证方式,使用APPID的方法已经玩不转了。每次使用前必须用一个access token的东东,你必须自己申请一个ClientID和Client密码。有兴趣了解详情的请参考

http://blogs.msdn.com/b/translation/p/gettingstarted1.aspx
http://api.microsofttranslator.com

 

Bing的API有3种调用接口,Ajax,SOAP,HTTP。我用Python搞,估计HTTP的方式更加合适我一点。我的只实现了部分接口,

我实现的Bing 翻译V2的接口包括,翻译,得到翻译候选列表,(一次翻译多个语句)设置翻译内容,得到语音等几个,其他的感觉有点多余,未必用得到。

还是多说无益,上代码,注释应该足够丰富,大家肯定看的明白。

 

# coding=utf-8
”’
Goolge translate API已经收费,我们的好日子没有了,
有两个选择,
1是直接用这些翻译功能的页面,然后将结果提取出来。
2.用bing的翻译API,微软这次终于上流了,可以每月用翻译200万的数据(其实就2M,还不知道他的浏览怎么算,),呵呵。
某种程度上,我最近玩的东西好像用bing翻译更上流一点,我先玩玩他,算是对我自己多年学习python的总结,
网上有些兄弟写过,但是大部分是是对于V1的版本的,V2版本改了验证方式
现在微软已经使用了新的验证方式,使用APPID的方法已经玩不转了。必须用一个access token的东东
清参考
http://blogs.msdn.com/b/translation/p/gettingstarted1.aspx
http://api.microsofttranslator.com

1 # coding=utf-8
2 ”’
3 网上有些兄弟写过,但是大部分是是对于V1的版本的,V2版本改了验证方式
4 现在微软已经使用了新的验证方式,使用APPID的方法已经玩不转了。必须用一个access token的东东
5
6 清参考
7 http://blogs.msdn.com/b/translation/p/gettingstarted1.aspx
8 http://api.microsofttranslator.com
9
10 ”’
11
12 import urllib
13 import urllib2
14 import json
15 import time
16 import unittest
17 import xml.etree.ElementTree
18
19
20
21 class Get_Translate_Data(object):
22 ”’
23 Get Translate 操作取回的数据的,解析后的得到的数据字段,
24 ”’
25 def __init__(self):
26 # #翻译结果匹配程度
27 self._match_degree = 0
28 # #翻译结果被用户选择的次数
29 self._selected_count = 0
30 # #翻译结果可以认可的比率,MS自己有一套规则,自己上参考网址看
31 self._rating = 0
32 # #返回的结果
33 self._translated_text = “”
34
35 def __str__(self):
36 return (“match_degree:%s selected_count:%s rating:%s translated_text:%s“)
37 % (self._match_degree, self._selected_count, self._rating, self._translated_text)
38
39
40 class Bing_Translator_API(object):
41 ”’
42 此工具用于使用bing的翻译API,让你快速的得到翻译的结果
43 我是按照2012年12月22日看到的API V2的要求实现的,
44 实现的Bing 翻译V2的接口包括,翻译,得到翻译候选列表,(一次翻译多个语句)设置翻译内容,得到语音,
45 ”’
46 # 最大请求的字符长度,微软的要求
47 REQ_STR_MAX_LEN = 10000
48 # add trascation 增加翻译的原文最大长度
49 ADD_ORIGINALTEXT_LEN = 1000
50 # add trascation 增加翻译的翻译文字长度
51 ADD_TRANSLATEDTEXT_LEN = 2000
52 # SPEEK string的最大值
53 SPEAK_STRING_LEN = 2000
54
55 # 最大返回的结果个数
56 RSP_RESULT_MAX_NUMBER = 10
57
58 # 取得acess token的两个参数,常量
59 ACCESS_TOKEN_REQ_SCOPE = “http://api.microsofttranslator.com“
60 ACCESS_TOKEN_REQ_GRANT_TYPE = “client_credentials“
61
62 # POST取得ACESS TOKEN的URL
63 ACCESS_TOKEN_REQ_URL = “https://datamarket.accesscontrol.windows.net/v2/OAuth2-13“
64 # GET方法得到翻译的结果,只得到一个结果,估计这个最常用
65 TRANSLATE_REQ_URL = “http://api.microsofttranslator.com/V2/Http.svc/Translate“
66 # POST取得翻译结果的结果的URL,这个是一次可以取回多个翻译结果
67 GET_TRANSLATE_REQ_URL = “http://api.microsofttranslator.com/V2/Http.svc/GetTranslations“
68 # 检测语句的语言
69 DETECT_REQ_URL = “http://api.microsofttranslator.com/V2/Http.svc/Detect“
70 # 增加翻译的URL
71 ADD_TRANSLATION_URL = “http://api.microsofttranslator.com/V2/Http.svc/AddTranslation“
72 # 发音的请求
73 SPEAK_REQ_URL = “http://api.microsofttranslator.com/V2/Http.svc/Speak“
74
75 # LC=language code,常用的几个都写在这儿,免得你还要查询
76 LC_CHINESE_SIMPLIFIED = “zh-CHS“
77 LC_CHINESE_TRADITIONAL = “zh-CHT“
78 LC_ENGLISH = “en“
79 LC_JAPANESE = “ja“
80 LC_KOREAN = “ko“
81 LC_FRENCH = “fr“
82 LC_GERMAN = “de“
83
84 def __init__ (self, client_id, client_secret, proxy_conf=None):
85 ”’
86 @param client_id 客户端ID,你在MS网址注册得到的ID
87 @param client_secret 客户端密钥
88 @param proxy_conf 代理配置,默认None,不配置,如果配置http,https都要写,
89 比如{‘http': ‘http://proxy.a.com:8080/’,’https': ‘http://proxy.a.com:8080/’},折腾了我一个下午
90 ”’
91
92 # 你请求获得acess token的两个参数,客户端ID,和一个验证密码
93 self._client_id = client_id
94 self._client_secret = client_secret
95
96 self._token_opener = None
97 self._api_opener = None
98
99 # 如果有代理,配置代理
100 if proxy_conf == None :
101 self._token_opener = urllib2.build_opener()
102 self._api_opener = urllib2.build_opener()
103 else:
104 self._token_opener = urllib2.build_opener(urllib2.ProxyHandler(proxy_conf), urllib2.HTTPSHandler())
105 self._api_opener = urllib2.build_opener(urllib2.ProxyHandler(proxy_conf), urllib2.HTTPHandler())
106
107 self._access_token = “”
108 self._expires_time = 0
109
110
111
112
113 def __get_acess_token(self, retry_num=3):
114 ”’
115 @brief 得到访问的access token,如果已经有了token,而且没有超时,就不继续使用原有的token
116 @retry_num 重试的次数
117 ”’
118 # 检查超时与否,如果没有超时,什么都不做
119 if (time.time() – 10 < self._expires_time):
120 return 0
121
122 post_data = urllib.urlencode({‘client_id‘:self._client_id,
123 ‘client_secret‘:self._client_secret,
124 ‘scope‘:Bing_Translator_API.ACCESS_TOKEN_REQ_SCOPE,
125 ‘grant_type‘:Bing_Translator_API.ACCESS_TOKEN_REQ_GRANT_TYPE })
126
127 retry_count = 0
128 resp_data = None
129
130 # 进行N词重试
131 while (retry_count < retry_num) :
132 try :
133 resp_data = self._token_opener.open(fullurl=Bing_Translator_API.ACCESS_TOKEN_REQ_URL,
134 data=post_data,
135 timeout=10)
136 except Exception, e:
137 retry_count += 1
138 self._token_opener.close()
139 print str(e), Bing_Translator_API.ACCESS_TOKEN_REQ_URL, retry_count
140 continue
141 break
142
143 self._token_opener.close()
144 if (retry_count == retry_num):
145 return -1
146
147 str_data = unicode(resp_data.read())
148
149 # 分析json得到数据和超时时间,
150 token_data = json.loads(str_data)
151 # 注意,不要解码,我画蛇添足的搞了1个小时才发现这个错误
152 self._access_token = token_data[“access_token“]
153 self._expires_time = time.time() + int(token_data[“expires_in“])
154
155 return 0
156
157 def translate(self, from_language, to_language , want_translate, content_type=“text/plain“, category=“general“, retry_num=3):
158 ”’
159 @brief 得到翻译,只有一个翻译结果,作为返回值返回,
160 @notice 这个方法使用的是GET 请求
161 @param from_language 翻译的语言,参考前面的LC_XXX定义
162 @param to_language
163 @param want_translate 要翻译的的文本信息,必须用UTF8的编码,
164 @param content_type “text/plain” 或者”text/html”
165 @param category 分类,估计可以提高翻译的准确度,但MS也没有告知我们可以填写啥,默认”general”
166 @return 一个元组,第一个数值是int,==0表示成功,第二个是成功后翻译的语句,
167 ”’
168 ret_text = “”
169
170 if (len(want_translate) > Bing_Translator_API.REQ_STR_MAX_LEN):
171 return (-1, ret_text)
172 # 检查token还是否有效,以及是否需要重新获取
173 ret = self.__get_acess_token(retry_num)
174 if (ret != 0):
175 return (ret, ret_text)
176
177 # print self._api_opener.addheaders
178 # 得到请求的URL
179 url_all = Bing_Translator_API.TRANSLATE_REQ_URL + “?“ + urllib.urlencode({‘text‘:want_translate,
180 ‘from‘:from_language,
181 ‘to‘:to_language,
182 ‘contentType‘:content_type,
183 ‘category‘:category })
184 url_req = urllib2.Request(url=url_all)
185 url_req.add_header(‘Authorization‘, ‘bearer ‘ + self._access_token)
186
187 retry_count = 0
188 resp_data = None
189 # 进行N次重试
190 while (retry_count < retry_num) :
191 try :
192 resp_data = self._token_opener.open(url_req, timeout=10)
193 except Exception, e:
194 retry_count += 1
195 print str(e), url_req, retry_count
196 continue
197 else:
198 break
199 finally:
200 self._token_opener.close()
201
202 if (retry_count == retry_num):
203 return (-1, ret_text)
204
205 # 解析XML结果得到数据
206 xml_str = resp_data.read()
207 tag = xml.etree.ElementTree.fromstring(xml_str)
208 ret_text = tag.text
209
210 return (0, ret_text)
211
212 def get_translate(self, from_language, to_language , want_translate, result_list,
213 content_type=“text/plain“, category=“general“, user=“”, uri=“”, retry_num=3):
214 ”’
215 @brief 得到翻译,可能有多个翻译的结果返回,返回的是一个列表,
216 @notice 这个方法使用的是GET 请求
217 @param result_list 返回参数,返回的翻译list的Get_Translator_Data
218 @param user 用户名称,默认为””,如果对翻译效果不满意,可以改为all
219 @param uri URI
220 @param 其他参数同translate函数,不多解释
221 @return 返回0表示成功,其他表示失败
222 ”’
223
224 if (len(want_translate) > Bing_Translator_API.REQ_STR_MAX_LEN):
225 return -1
226 # 检查token还是否有效,以及是否需要重新获取
227 ret = self.__get_acess_token(retry_num)
228 if (ret != 0):
229 return ret
230
231
232 # 得到请求的URL
233 url_all = Bing_Translator_API.GET_TRANSLATE_REQ_URL + “?“ + urllib.urlencode({‘text‘:want_translate,
234 ‘from‘:from_language,
235 ‘to‘:to_language,
236 ‘maxTranslations‘:Bing_Translator_API.RSP_RESULT_MAX_NUMBER })
237
238 # 其实不发送下面Post数据也可以发送请求(发送参数=””,不能不写,否则是GET请求),也可以得到结果,我测试过。增加下面这段反而又让我调试了半天
239 # Post 请求的参数,里面的State是一个事务ID,请求带过去,返回的结果,MS给你带回来,你要希望使用,自己改造
240 # 这样的到的翻译很多,但效果感觉比较糟糕,估计有些是用户添加的,如果你不喜欢,可以在User的值改为all
241 post_data = “<TranslateOptions xmlns=”http://schemas.datacontract.org/2004/07/Microsoft.MT.Web.Service.V2″>“
242 “<Category>%s</Category>“
243 “<ContentType>%s</ContentType>“
244 “<ReservedFlags></ReservedFlags>“
245 “<State>20121221</State>“
246 “<Uri>%s</Uri>“
247 “<User>%s</User>“
248 “</TranslateOptions>“ % (category, content_type, uri, user)
249
250
251 url_req = urllib2.Request(url=url_all, data=post_data)
252 url_req.add_header(‘Authorization‘, ‘bearer ‘ + self._access_token)
253 # 如果要加post数据,这行必须加,否返回500的错误,看了半天C#的例子
254 url_req.add_header(‘Content-Type‘, ‘text/xml‘)
255 retry_count = 0
256 resp_data = None
257 # 进行N次重试
258 while (retry_count < retry_num) :
259 try :
260 resp_data = self._token_opener.open(url_req, timeout=10)
261 except Exception, e:
262 retry_count += 1
263 print str(e), url_req, retry_count
264 continue
265 else:
266 break
267 finally:
268 self._token_opener.close()
269
270 if (retry_count == retry_num):
271 return -1
272
273 # 倒霉的XML namespace,麻烦死了
274 MS_GETTRNS_NAMESPACES = “http://schemas.datacontract.org/2004/07/Microsoft.MT.Web.Service.V2“
275
276 xml_str = resp_data.read()
277 tag = xml.etree.ElementTree.fromstring(xml_str)
278 # 前面非要家那个.//,而且还必须有那个XML的名字空间{http://schemas.datacontract.org/2004/07/Microsoft.MT.Web.Service.V2}
279 tans_list = tag.findall(“.//{%s}TranslationMatch“ % MS_GETTRNS_NAMESPACES)
280 for tag_item in tans_list:
281 trans_data = Get_Translate_Data()
282 for iter_item in tag_item.iter():
283 if iter_item.tag == “{%s}Count“ % MS_GETTRNS_NAMESPACES:
284 trans_data._selected_count = int(iter_item.text)
285 if iter_item.tag == “{%s}MatchDegree“ % MS_GETTRNS_NAMESPACES:
286 trans_data._match_degree = int(iter_item.text)
287 if iter_item.tag == “{%s}Rating“ % MS_GETTRNS_NAMESPACES:
288 trans_data._rating = int(iter_item.text)
289 if iter_item.tag == “{%s}TranslatedText“ % MS_GETTRNS_NAMESPACES:
290 trans_data._translated_text = iter_item.text
291 # print trans_data
292 result_list.append(trans_data)
293 return 0
294
295 def detect(self, detect_text, retry_num=3):
296 ”’
297 @brief 检查语句的语言
298 @notice 这个方法使用的是GET 请求
299 @param detect_text 检测的语句,必须用UTF8的编码,
300 @return 一个元组,第一个数值是int,==0表示成功,否则表示失败,第二个是成功后返回语言的标识,如果失败,返回”
301 ”’
302 ret_text = “”
303
304 if (len(detect_text) > Bing_Translator_API.REQ_STR_MAX_LEN):
305 return (-1, ret_text)
306 # 检查token还是否有效,以及是否需要重新获取
307 ret = self.__get_acess_token(retry_num)
308 if (ret != 0):
309 return (ret, ret_text)
310
311 # print self._api_opener.addheaders
312 # 得到请求的URL
313 url_all = Bing_Translator_API.DETECT_REQ_URL + “?“ + urllib.urlencode({‘text‘:detect_text})
314 url_req = urllib2.Request(url=url_all)
315 url_req.add_header(‘Authorization‘, ‘bearer ‘ + self._access_token)
316
317 retry_count = 0
318 resp_data = None
319 # 进行N次重试
320 while (retry_count < retry_num) :
321 try :
322 resp_data = self._token_opener.open(url_req, timeout=10)
323 except Exception, e:
324 retry_count += 1
325 print str(e), url_req, retry_count
326 continue
327 else:
328 break
329 finally:
330 self._token_opener.close()
331
332 if (retry_count == retry_num):
333 return (-1, ret_text)
334
335 # 解析XML结果得到数据
336 xml_str = resp_data.read()
337 tag = xml.etree.ElementTree.fromstring(xml_str)
338 ret_text = tag.text
339
340 return (0, ret_text)
341
342 def add_translation(self, original_text, translated_text, from_language, to_language, user,
343 rating=1, content_type=“text/plain“, category=“general“, uri=“”, retry_num=3):
344 ”’
345 @brief 增加翻译内容,用于改善后面的翻译
346 @notice 这个方法使用的是GET 请求
347 @param original_text 原文
348 @param translated_text 已经翻译的原文
349 @param from_language
350 @param to_language
351 @param usr 用户名称,估计在get的时候会有一些作用
352 @param rating -10~10
353 @param content_type “text/plain” 或者”text/html”
354 @param category 分类,估计可以提高翻译的准确度,但MS也没有告知我们可以填写啥,默认”general”
355 @param uri
356 @param retry_num 重试次数
357 @return 返回0表示成功,其他表示失败
358 ”’
359
360 if (len(original_text) > Bing_Translator_API.ADD_ORIGINALTEXT_LEN):
361 return -1
362 if (len(translated_text) > Bing_Translator_API.ADD_TRANSLATEDTEXT_LEN):
363 return -1
364 # 检查token还是否有效,以及是否需要重新获取
365 ret = self.__get_acess_token(retry_num)
366 if (ret != 0):
367 return (ret, ret_text)
368
369 # print self._api_opener.addheaders
370 # 得到请求的URL
371 url_all = Bing_Translator_API.ADD_TRANSLATION_URL + “?“ + urllib.urlencode({‘originalText‘:original_text,
372 ‘translatedText‘:translated_text,
373 ‘from‘:from_language,
374 ‘to‘:to_language,
375 ‘rating‘:rating,
376 ‘contentType‘:content_type,
377 ‘category‘:category,
378 ‘user‘:user,
379 ‘uri‘:uri })
380 url_req = urllib2.Request(url=url_all)
381 url_req.add_header(‘Authorization‘, ‘bearer ‘ + self._access_token)
382
383 retry_count = 0
384 resp_data = None
385 # 进行N次重试
386 while (retry_count < retry_num) :
387 try :
388 resp_data = self._token_opener.open(url_req, timeout=10)
389 except Exception, e:
390 retry_count += 1
391 print str(e), url_req, retry_count
392 continue
393 else:
394 break
395 finally:
396 self._token_opener.close()
397
398 if (retry_count == retry_num):
399 return -1
400
401 return 0
402
403
404 def speak(self, speak_text, language, format=“audio/wav“, options=“MinSize“, retry_num=3):
405 ”’
406 @brief 得到翻译,可能有多个翻译的结果返回,返回的是一个列表,
407 @notice 这个方法使用的是GET 请求
408 @param speak_text
409 @param language 语言
410 @param format 为 audio/wav 或者 audio/mp3
411 @param options 为“MaxQuality” 或者 “MinSize”
412 @return 返回0表示成功,其他表示失败
413 ”’
414
415 if (len(speak_text) > Bing_Translator_API.SPEAK_STRING_LEN):
416 return -1
417 # 检查token还是否有效,以及是否需要重新获取
418 ret = self.__get_acess_token(retry_num)
419 if (ret != 0):
420 return ret
421
422 ret_speak = “”
423 # 得到请求的URL
424 url_all = Bing_Translator_API.SPEAK_REQ_URL + “?“ + urllib.urlencode({‘text‘:speak_text,
425 ‘language‘:language,
426 ‘format‘:format,
427 ‘options‘:options })
428 url_req = urllib2.Request(url=url_all)
429 url_req.add_header(‘Authorization‘, ‘bearer ‘ + self._access_token)
430
431 retry_count = 0
432 resp_data = None
433 # 进行N次重试
434 while (retry_count < retry_num) :
435 try :
436 resp_data = self._token_opener.open(url_req, timeout=10)
437 except Exception, e:
438 retry_count += 1
439 print str(e), url_req, retry_count
440 continue
441 else:
442 break
443 finally:
444 self._token_opener.close()
445
446 if (retry_count == retry_num):
447 return (-1, ret_speak)
448
449 # 解析XML结果得到数据
450 ret_speak = resp_data.read()
451
452 return (0, ret_speak)
453
454 #单元测试,单元测试
455 class Test_Bing_Translator_API(unittest.TestCase):
456
457 def setUp(self):
458 # self._test_api = Bing_Translator_API(client_id=”你的客户端ID”,
459 # client_secret=”你的客户端密钥”)
460 self._test_api = Bing_Translator_API(client_id=“你的客户端ID“,
461 client_secret=“你的客户端密钥“,
462 proxy_conf={‘http‘: ‘你的代理服务器:端口/‘, ‘https‘: ‘你的代理服务器:端口‘})
463
464
465 def test_translate(self):
466 ret, trans_str = self._test_api.translate(Bing_Translator_API.LC_CHINESE_SIMPLIFIED,
467 Bing_Translator_API.LC_ENGLISH,
468 “中华人民共和国“);
469 print ret , trans_str
470
471 test_string = “中华人民共和国“
472 test_gb2312 = test_string.encode(‘gb2312‘)
473 # 这个地方翻译会错误,所以编码不能用GB2312这类编码
474 ret, trans_str = self._test_api.translate(Bing_Translator_API.LC_CHINESE_SIMPLIFIED,
475 Bing_Translator_API.LC_ENGLISH,
476 test_gb2312);
477 print ret , trans_str
478
479 def test_get_translate(self):
480 result_list = []
481 ret = self._test_api.get_translate(Bing_Translator_API.LC_CHINESE_SIMPLIFIED,
482 Bing_Translator_API.LC_ENGLISH,
483 “中华人民共和国“,
484 result_list);
485 for trans_data in result_list :
486 print trans_data
487 result_list = []
488 ret = self._test_api.get_translate(Bing_Translator_API.LC_ENGLISH,
489 Bing_Translator_API.LC_CHINESE_SIMPLIFIED,
490 “to“,
491 result_list);
492 for trans_data in result_list :
493 print trans_data
494
495 def test_detect(self):
496 ret, detect_lan = self._test_api.detect(“中华人民共和国“)
497 print ret, detect_lan
498 ret, detect_lan = self._test_api.detect(“made in china“)
499 print ret, detect_lan
500
501 def test_add_translation(self):
502 ret = self._test_api.add_translation(original_text=“china“,
503 translated_text=“瓷器“,
504 from_language=Bing_Translator_API.LC_ENGLISH,
505 to_language=Bing_Translator_API.LC_CHINESE_SIMPLIFIED,
506 user=“fullsail“)
507 print ret
508 result_list = []
509 ret = self._test_api.get_translate(Bing_Translator_API.LC_ENGLISH,
510 Bing_Translator_API.LC_CHINESE_SIMPLIFIED,
511 “china“,
512 result_list,
513 user=“fullsail“);
514 for trans_data in result_list :
515 print trans_data
516
517
518 def test_speek(self):
519 ret, ret_speak = self._test_api.speak(speak_text=“人一走,茶就凉,是自然规律;人没走,茶就凉,是世态炎凉。一杯茶,佛门看到的是禅,道家看到的是气,儒家看到的是礼,商家看到的是利。茶说:我就是一杯水,给你的只是你的想像,你想什么,什么就是你。心即茶,茶即心。“,
520 language=Bing_Translator_API.LC_CHINESE_SIMPLIFIED);
521
522
523 file_hdl = open(“D:\123.wav“, “wb+“)
524 file_hdl.write(ret_speak)
525 file_hdl.close()
526
527
528 if __name__ == ‘__main__‘:
529 unittest.main()
530

 

 

最早看python应该是8年前了,但直到最近2个月才使用,计算机是实践科学,看了不用,等于浪费,没有任何效果 这次算是一个小小的进步。

 

【本文作者是雁渡寒潭,本着自由的精神,你可以在无盈利的情况完整转载此文档,转载时请附上BLOG链接:http://www.cnblogs.com/fullsail/ 或者http://blog.csdn.net/fullsail,否则每字一元,每图一百不讲价。对Baidu文库。360doc加价一倍】

想得卻不可得 你奈人生何 該捨的捨不得 只顧著跟往事瞎扯

本文链接无觅关联推荐[?]

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
Python:TTS语音合成技术,市场各大平台对比以及实现
微信小程序后台开发详解
Django微信公众号开发(一)公众号内网页授权登录后微信获取用户信息
Django中使用Celery执行异步和定时任务的注意事项
[Qt Topic] – 中文化研习,做一个多语言的简易天气预报器
上海财经大学:消息中心点亮智慧校园
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服