QQ机器人,作用 不大,意义却不小 。此次采用轻处理方式实现,不设计QQ协议以及什么登陆加密方式等等问题研究。从web版QQ切入。
整个设计思路:用c#的webbrowser控件加载web QQ,以webQQ正常的登陆方式登陆,登陆以后,检测收到的信息(好友信息、QQ群信息)加以分析(包括分词技术),做出应答对策(搜索 特定应答库或其它网络资源)
下面是核心技术要点:
1、WebBrowser 控件
用这个控件加载http://w.qq.com/这个地址时,发现网页根本 打不开,出现版本提示
解决 办法:在Navigate这个地址前面 加个版本控制 的方法
WebBrowserVersionEmulation();
webBrowser1.Navigate("http://w.qq.com/");
WebBrowserVersionEmulation方法的具体内容如下:
private static void WebBrowserVersionEmulation()
{
const string BROWSER_EMULATION_KEY =
@"Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION";
String appname = Process.GetCurrentProcess().ProcessName + ".exe";
// Webpages are displayed in IE9 Standards mode, regardless of the !DOCTYPE directive.
const int browserEmulationMode = 9999;
RegistryKey browserEmulationKey =
Registry.CurrentUser.OpenSubKey(BROWSER_EMULATION_KEY, RegistryKeyPermissionCheck.ReadWriteSubTree) ??
Registry.CurrentUser.CreateSubKey(BROWSER_EMULATION_KEY);
if (browserEmulationKey != null)
{
browserEmulationKey.SetValue(appname, browserEmulationMode, RegistryValueKind.DWord);
browserEmulationKey.Close();
}
}
对于winform程序来说,复杂操作通常需要使用多线程解决界面卡死的问题,但是比多线程更简便的方式是Application.DoEvents()
while(true)
{
//getMsg();耗时很长的操作
Application.DoEvents();
}
2、使用HtmlAgilityPack解析网页源码,获取消息
public void getMsg()
{
string html = webBrowser1.Document.Body.InnerHtml;
HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
doc.LoadHtml(html);
HtmlNode chatdiv = doc.GetElementbyId("panelBody-5");
if (chatdiv != null)
{
HtmlNodeCollection list = chatdiv.SelectNodes("//div[@class='chat_content_group buddy ']");
if (list != null)
{
string nickname = list[list.Count - 1].ChildNodes[3].InnerText.Trim();
string saywords = list[list.Count - 1].ChildNodes[5].InnerText.Trim();
if (nickname != up_nickname || saywords != up_saywords)
{
this.Text = nickname + " 说:" + saywords;
up_nickname = nickname;
up_saywords = saywords;
string msg = GetMsg(nickname, saywords);
if (msg.Trim() != "")
{
sendMsg(msg);
}
}
}
}
}
3、Lucene.Net +盘古分词
public List<string> getFC(string txt)
{
Analyzer analyzer = new PanGuAnalyzer();
TokenStream ts = analyzer.TokenStream("",new StringReader(txt) );
List<string> wordlist=new List<string> ();
Lucene.Net.Analysis.Token token = null;
while ( (token=ts.Next() ) != null)
{
if (token.TermText().Length > 1)
{
wordlist.Add(token.TermText());
}
}
return wordlist;
}
4、将接收到的QQ消息进行分词处理 ,对分词结果进行分析 ,得到相应 的应答内容,模拟发送消息。
public void sendMsg(string msg)
{
webBrowser1.Document.GetElementById("chat_textarea").InnerText =msg;
webBrowser1.Document.GetElementById("send_chat_btn").InvokeMember("click");
}