先来看一下程序界面以及效果
首先如Title,是百度的翻译。因为英文水平有限,所以每次都求翻译,有一次注意到百度的翻译不需要登录就可以翻译,于是就猜到只要发送正确的请求就一定能获得服务器返回的数据。所以照着百度翻译的界面开始搞起来。
一:监视请求,捕获有用的请求地址
我用的是谷歌浏览器,直接按 F12 就可以监视请求了。
二:分析地址和参数
通过监视请求,发现语言类型判断地址 http://fanyi.baidu.com/langdetect
判断语言类型的参数只有一个 query:待翻译内容【即便是汉字也不需要进行 HttpUtility.UrlEncode操作】
返回数据的格式如上图。{"error":0,"msg":"success","lan":"zh"} 格式不变,其中 lan后的值就是服务器判断出的语言类型
翻译地址是 http://fanyi.baidu.com/v2transapi
翻译所需参数有四个 from :从什么语言
to : 翻译为什么语言
query:翻译的内容 【汉字等需要经过HttpUtility.UrlEncode操作】
transtype :trans 【不知道干什么的参数,我一直都带着】
语言的参数有以下几种,我都给大家收集完毕了
string[] strsLan = { "auto-自动检测","ara-阿拉伯语", "de-德语", "ru-俄语", "fra-法语", "kor-韩语", "nl-荷兰语", "pt-葡萄牙语", "jp-日语", "th-泰语", "wyw-文言文", "spa-西班牙语", "el-希腊语","it-意大利语","en-英语","yue-粤语","zh-中文" };
返回参数格式如下图:
如图所示:dst后的数据就是一条一条翻译的数据,亲,data下不止一条数据哦。我这里测试的不全,返回的 数据格式 我记得有时候是变化的
在这里,我能想到的简单的操作是 用FrameWork4.0及更高版本,然后去引入 Newtonsoft.Json.dll 去处理Json数据,或者干脆写网页程序,Ajax中设置 dataType:"json"。
但是我写的WinForm程序是3.5版本的,为了就是能在Win7电脑上直接用。
三:正则解析
所以我决定用 正则表达式 匹配结果
正则表达式匹配的那段代码如下:【返回的数据很多,我只取出直接翻译的内容进行拼接,如果大家想像百度翻译那样,多解析点东西就好了】
Regex reg = new Regex(@"(""dst"":""([^""]+)"")"); MatchCollection mat = reg.Matches(resultStr); if (mat.Count > 0) { string strs = ""; string str = ""; foreach (Match m in mat) { //txt_from.Text += "\r\n" + mat.Groups[0]; str = m.Groups[2].ToString(); //如果是汉字的unicode,转换 if (str.Contains('\\')) { str = ToGB2312(str); } strs += str+"\r\n\r\n"; } txt_to.Text = strs; } else { MessageBox.Show("没有匹配项"); }
代码很简单,我解释下正则匹配项
四:引用传值
最后解释下这个语言选择Form
这是个窗体
设置 ShowInTaskbar 属性为False【确定窗体是否出现Windows任务栏中】
设置 FormBorderStyle属性为None【指示窗体的边框和标题栏的外观和行为】如此,窗体就不像窗体了,更像个用户控件
注意:这个选择语言的Form只能用Show()方法,不能用ShowDialog()方法,否则无法触发 失去焦点事件。
绑定 Deactivate 事件或 Leave事件 ,代码如下【这样当这个窗体失去焦点后,自动消失,用户体验好】
private void Frm_Language_Leave(object sender, EventArgs e) { this.Close(); }
绑定 Load 事件,代码如下【为按钮加点击事件,其中 Btn是这个窗体初始化的时候传入的,Button是引用类型,对传入的参数操作,会影响原Button的】
public Button Btn { get; set; } public Frm_Language() { InitializeComponent(); } private void Frm_Language_Load(object sender, EventArgs e) { if (Btn.Text.StartsWith("目标语言")) { btn_auto.Enabled = false; } string langSelect = Btn.Tag.ToString();//拿到传入的语言是哪个 foreach (var control in this.Controls) { if (control.GetType().Name == "Button") { Button bt = (Button)control; if (bt.Text != "取消") { bt.Click += new EventHandler(bt_Click); if (bt.Name.EndsWith(langSelect)) { bt.Select(); } } } } }
void bt_Click(object sender, EventArgs e) { Btn.Tag = ((Button)sender).Name.Substring(4); if (Btn.Text.StartsWith("源语言")) { Btn.Text = "源语言:" + ((Button)sender).Text; } else { Btn.Text = "目标语言:" + ((Button)sender).Text; } this.Close(); }
五:一些辅助方法
C#发送 Post请求的方法
private string PostWebRequest(string postUrl, string paramData, Encoding dataEncode) { string ret = string.Empty; try { byte[] byteArray = dataEncode.GetBytes(paramData); //转化 HttpWebRequest webReq = (HttpWebRequest)WebRequest.Create(new Uri(postUrl)); webReq.Method = "POST"; webReq.ContentType = "application/x-www-form-urlencoded"; webReq.ContentLength = byteArray.Length; Stream newStream = webReq.GetRequestStream(); newStream.Write(byteArray, 0, byteArray.Length);//写入参数 newStream.Close(); HttpWebResponse response = (HttpWebResponse)webReq.GetResponse(); StreamReader sr = new StreamReader(response.GetResponseStream(), Encoding.Default); ret = sr.ReadToEnd(); sr.Close(); response.Close(); newStream.Close(); } catch (Exception ex) { return ex.Message; } return ret; }
C#将Unicode编码转换为汉字字符串
/// <summary> /// 将Unicode编码转换为汉字字符串 /// </summary> /// <param name="str">Unicode编码字符串</param> /// <returns>汉字字符串</returns> public static string ToGB2312(string str) { string r = ""; MatchCollection mc = Regex.Matches(str, @"\\u([\w]{2})([\w]{2})", RegexOptions.Compiled | RegexOptions.IgnoreCase); byte[] bts = new byte[2]; foreach (Match m in mc) { bts[0] = (byte)int.Parse(m.Groups[2].Value, NumberStyles.HexNumber); bts[1] = (byte)int.Parse(m.Groups[1].Value, NumberStyles.HexNumber); r += Encoding.Unicode.GetString(bts); } return r; }