前天公司面试题-使用B/S模式写一个程序,用来抓取百度或SOSO中对关键字的说明,尽量不使用服务器控件。
2012-07-14 22:34
405 查看
从帝都回到长沙快一周了,一切都比较顺利,回长沙之间就联系了几家公司,前天去面试了,去了后测试题就只有一道:抓取从百度或SOSO对关键字的解释说明,使用B/S模式。
想了想还是挺容易的一开始的思路所想的思路是这样的。
1.使用一个HTML页面,放一个文本框,一个按钮,一个DIV容器。点击按钮取到文本框的内容,异步的发送AJAX请求至后台的ashx。
2.在后面的ASHX页面,接收传过来的关键字,用一个webclient来下载SOSO的关键字页面的源代码,拿到页面源代码后,分析有关关键字的解释说明的格式,使用正则去匹配。将匹配上的存到一个集合中。再把集合中的内容组装成JSON格式发住前台。
3.在前台接收到JSON数据后,再动态的放到DIV容器中。
主要代码如下:
前台页面代码:
ASHX页面代码如下:
其实测试的时候,我最开始是抓的百度的,但对于百度的要抓的内容是如下格式:
<br><font size=-1><font color=#CC0000>耳鼻喉</font>,国家重点(医保十佳)规模,名医荟萃,技术精湛,连续10年患者口碑最佳.微创技术,不开刀,有效治疗,7月感恩活动季,费用最低,成功率NO.1即刻预约享手术费半价优惠.</font><br>
<br><font size=-1><font color=#CC0000>耳鼻喉</font> 国防科大医院是湘雅医院双向转诊合作医院,省市医保!国家二级甲等医院,59年公立医院历史,专业<font color=#CC0000>耳鼻喉</font>专家亲诊,<font color=#CC0000>耳鼻喉</font>权威疗法,标本兼治</font><br>
最失败的是测试的时候用正则来匹配这一格式的内容我卡壳了。不过急中生智为了通过测试,保正程序完整能通过,我自己把要抓的内容改成了抓取页面上的所有超链接。这样就只要再去改正则就完事了。后来下午才知道,这个小测试居然是公司正好要用的东西。直接放到面试的时候让面试的人来写了,想法真好。当然测试也小通过。下午告诉我他们要抓SOSO的让我改用SOSO的 下午不是测试就不急不忙了 把正则和一些细节的东西改好交给他们了。
有时候个人觉得,应聘时,机试题可以适当的自己改改需求,首先是要保证能跑起来就行,然后代码风格一定要规范,专业。引用我启蒙老师最喜欢的话就是:“命名即注释;该有注释的地方不要省,说不定个把月后你拿到以前自己写的代码没有注释也要理上半天才能理清。”
想了想还是挺容易的一开始的思路所想的思路是这样的。
1.使用一个HTML页面,放一个文本框,一个按钮,一个DIV容器。点击按钮取到文本框的内容,异步的发送AJAX请求至后台的ashx。
2.在后面的ASHX页面,接收传过来的关键字,用一个webclient来下载SOSO的关键字页面的源代码,拿到页面源代码后,分析有关关键字的解释说明的格式,使用正则去匹配。将匹配上的存到一个集合中。再把集合中的内容组装成JSON格式发住前台。
3.在前台接收到JSON数据后,再动态的放到DIV容器中。
主要代码如下:
前台页面代码:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" > <head> <title>CatchDemo</title> <script src="JS/jquery-1.7.2.js" type="text/javascript"></script> <script type="text/javascript"> $(function(){ $("#btn_submit").click(function(){ //注册点击事件 var kword=$("#txt_keyword").val(); //取得文本框的内容 $("#contentlist").empty(); //再次搜索前清空容器 $.post("CatchDemo.ashx",{kword:kword},function(data){ //发送异步请求 var json =eval(data); //将返回过来的JSON字符串解析成数组 alert(json.length); for(var i=0;i<json.length;i++) //遍历数组并动态添加DIV,在DIV中添加解析出来的文本 { var $row=$("<div></div>"); $row.text(json[i].row) $("#contentlist").append($row); } }); }); }) </script> </head> <body> <input type="text" id="txt_keyword" value="耳鼻喉" /> <input type="button" id="btn_submit" value="submit"/> <div id="contentlist"> </div> </body> </html>
ASHX页面代码如下:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Net; using System.Text; using System.Text.RegularExpressions; using System.Web.Services; namespace Ent.Xuz.CatchDemo { /// <summary> /// $codebehindclassname$ 的摘要说明 /// </summary> [WebService(Namespace = "http://tempuri.org/")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] public class CatchDemo : IHttpHandler { public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/plain"; string kword = context.Request.Form["kword"]; //从上一个面面接受来的参数 kword = context.Server.UrlEncode(kword); //进入URL编码 string url1 = @"http://www.soso.com/q?w="; //SOSO的搜索地址 string urlpath = url1 + kword; //拼接编码后的URL地址 string webcode = GetRCodeFormWC(urlpath); //得到源文件,待分析出特定字符串 List<string> list = GetInformationNow(webcode); //获得所需信息,放到list集合中,待转化为json发向前台 string jsonres = ListToJson(list); //转化JSON数组 //string jsonres = ListToString(list); //转化为**|***|**的格式/暂时不用 context.Response.Write(jsonres); } /// <summary> /// 创建webclient并通过构建好的地址下载源文件 /// </summary> /// <param name="path">URL地址</param> /// <returns></returns> private string GetRCodeFormWC(string path) { WebClient wc = new WebClient(); wc.Encoding = Encoding.Default; //避免乱码对其进行Default编码;百度的是UTF8格式的(起先用的UTF8乱码) return wc.DownloadString(path); } /// <summary> /// 对获取到的源文件,通过正则进行抓取,将抓取的内容放到List集合中 /// </summary> /// <param name="buffer">源文件内容</param> /// <returns></returns> private List<string> GetInformation(string buffer) { List<string> list = new List<string>(); // string rexstr = "href=\"([^\"]+)"; //抓取页面里的超链接 以href="开始,直到出现下一个引号时终止; string rexstr = "<p class=\"ds\">([^p]+)"; MatchCollection mc = Regex.Matches(buffer, rexstr); foreach (Match item in mc) { if (item.Success) { string temp = item.Groups[1].Value; //中华网健康频道<em>耳鼻喉</em>专题介绍神经性耳聋、中耳炎、老年性耳聋,药物性耳鸣、神经性耳鸣、过敏性鼻炎、鼻窦炎、鼻息肉、慢性鼻炎耳鸣、耳聋等<em>耳鼻喉</em>顽症信息。...</ //temp = temp.Replace("<em>","").Replace("</em>","").Replace("</",""); //暂时先用Replace解决,把<em>,</em>,</ 替换成空删除 temp= Regex.Replace(temp, @"<em>|</em>|</", ""); list.Add(temp); } } return list; } /// <summary> /// 对获取到的源文件,通过正则进行抓取,将抓取的内容放到List集合中 /// </summary> /// <param name="buffer">源文件内容</param> /// <returns></returns> private List<string> GetInformationNow(string buffer) { List<string> list = new List<string>(); string resstar = "<em>|</em>|<span class=\"ask\">|</span>"; //先空删除源文件中的<em>|</em>|<span class=\"ask\">|</span>标签 string temp = Regex.Replace(buffer, resstar, ""); string rexstr = "<p class=\"ds\">([^p]+)"; //再抓取页面中以 <p class="ds">开头 直到再次出现p标记终止 MatchCollection mc = Regex.Matches(temp, rexstr); //得到 "字符串...</" foreach (Match item in mc) { if (item.Success) { string temp1 = item.Groups[1].Value; temp1 = Regex.Replace(temp1, "</", ""); //再将"</"空删除 list.Add(temp1); } } return list; } #region 转化为字符串**|**|的格式 /// <summary> /// 将存放在list中的信息转换字符串**|**|的格式 /// </summary> /// <param name="list"></param> /// <returns></returns> private string ListToString(List<string> list) { StringBuilder builder = new StringBuilder(); foreach (string item in list) { builder.Append(item + "|"); } string temp = builder.ToString().TrimEnd('|'); return temp; } #endregion /// <summary> /// 将存放在list中的信息转换成JSON格式的数据 /// </summary> /// <param name="list"></param> /// <returns></returns> private string ListToJson(List<string> list) { StringBuilder builder = new StringBuilder(); //[{"row":content},{"row":content},{"row":content}]将数据拼接成此格式 builder.Append("["); for (int i = 0; i < list.Count; i++) { builder.AppendFormat("{{\"row\":\"{0}\"}},", list[i].ToString()); } string buffer = builder.ToString(); buffer = buffer.TrimEnd(','); buffer = buffer + "]"; return buffer; } public bool IsReusable { get { return false; } } } }
其实测试的时候,我最开始是抓的百度的,但对于百度的要抓的内容是如下格式:
<br><font size=-1><font color=#CC0000>耳鼻喉</font>,国家重点(医保十佳)规模,名医荟萃,技术精湛,连续10年患者口碑最佳.微创技术,不开刀,有效治疗,7月感恩活动季,费用最低,成功率NO.1即刻预约享手术费半价优惠.</font><br>
<br><font size=-1><font color=#CC0000>耳鼻喉</font> 国防科大医院是湘雅医院双向转诊合作医院,省市医保!国家二级甲等医院,59年公立医院历史,专业<font color=#CC0000>耳鼻喉</font>专家亲诊,<font color=#CC0000>耳鼻喉</font>权威疗法,标本兼治</font><br>
最失败的是测试的时候用正则来匹配这一格式的内容我卡壳了。不过急中生智为了通过测试,保正程序完整能通过,我自己把要抓的内容改成了抓取页面上的所有超链接。这样就只要再去改正则就完事了。后来下午才知道,这个小测试居然是公司正好要用的东西。直接放到面试的时候让面试的人来写了,想法真好。当然测试也小通过。下午告诉我他们要抓SOSO的让我改用SOSO的 下午不是测试就不急不忙了 把正则和一些细节的东西改好交给他们了。
有时候个人觉得,应聘时,机试题可以适当的自己改改需求,首先是要保证能跑起来就行,然后代码风格一定要规范,专业。引用我启蒙老师最喜欢的话就是:“命名即注释;该有注释的地方不要省,说不定个把月后你拿到以前自己写的代码没有注释也要理上半天才能理清。”
相关文章推荐
- 简单说明什么是递归,什么情况下会使用递归,并写一个简单的递归程序。
- 使用多线程方法实现一个死锁程序,用来提醒自己不要犯这样的错误
- 简单说明什么是递归,什么情况下会使用递归,并写一个简单的递归程序。
- 学习API HOOK,编写了一个winsock 的封包抓取程序,可免费使用;
- 用Go写了一个相似Proxy的小程序,能够用来訪问goolge个人使用还是能够的.
- 简单说明什么是递归?什么情况会使用?并使用Java实现一个简单的递归程序。
- 简单说明什么是递归,什么情况下会使用递归,并写一个简单的递归程序。
- 编写一个程序,使用fork函数来创建一个子进程,并且说明父进程和子进程的随机返回问题
- 简单说明什么是递归,什么情况下会使用递归,并写一个简单的递归程序。
- 32. 百度面试题:用天平(只能比较,不能称重)从一堆小球中找出其中唯一一个较轻的,使用x次天平,最多可以从y个小球中找出较轻的那个,求y与x的关系式
- 用Go写了一个类似Proxy的小程序,可以用来访问goolge个人使用还是可以的.
- 简单说明什么是递归,什么情况下会使用递归,并写一个简单的递归程序。
- 【Java面试题】23 java中有几种方法可以实现一个线程?用什么关键字修饰同步方法? stop()和suspend()方法为何不推荐使用?
- 面试题:使用final关键字修饰一个变量时,是引用不能变,还是引用的对象不能变?
- 简单说明什么是递归,什么情况下会使用递归,并写一个简单的递归程序。
- 我写的一个从百度服务器获取应答的程序_本来想获取百度首页的源代码的
- 5、 java 编写程序拷贝一个文件, 尽量使用效率高的方式.
- 简单说明什么是递归,什么情况下会使用递归,并写一个简单的递归程序。
- 简单说明什么是递归,什么情况下会使用递归,并写一个简单的递归程序。