抓取百度联想词配合jquery autocomplete插件,轻松达到百度首页搜索自动提示效果。

最近项目中很多文本框用需要用jquery-autocomplete插件做自动提示,以增强用户体验,但是出现的问题是,要很多自动显示的词,怎么办?

于是借助公司另外一个项目的经验(算是山寨吧!),干脆把百度首页的自动提示移植到项目中。

先贴效果,这是百度首页

这是demo效果

实现方式蛮简单的,用firebug获取文本框触发事件响应url就行了。

工具类代码如下

  1 import java.io.IOException;
2 import java.io.InputStream;
3 import java.io.InputStreamReader;
4 import java.io.UnsupportedEncodingException;
5 import java.net.HttpURLConnection;
6 import java.net.MalformedURLException;
7 import java.net.URL;
8 import java.net.URLEncoder;
9 import java.util.ArrayList;
10 import java.util.List;
11 import java.util.regex.Matcher;
12 import java.util.regex.Pattern;
13 import net.sf.json.JSONArray;
14
15 public class BaiduSuggestionUtil {
16 /**
17 * 获取百度的联想词
18 *
19 * @param input
20 * 通过firebug获取请求url
21 * <script src="http://unionsug.baidu.com/su?wd=zhong&amp;cb=window.bdsug.sug&amp;from=superpage&amp;t=1314710713843" charset="gb2312">
22 * </script>
23 * @return
24 */
25 public static final String BAIDU_HOST = "http://unionsug.baidu.com";
26 public static final String QUERY_PATH = "/su?wd=";
27 public static final String PARAMETER = "&amp;cb=window.bdsug.sug&amp;from=superpage&amp;t=";
28 public static final String REFERER_HEADER = "Referer";
29 public static final String REFERER = "http://www.baidu.com/";
30 public static final String BAIDU_SUG_REG = "\"[\\s\\S]*?\"";
31 private InputStream in = null;
32 private InputStreamReader inr = null;
33 private HttpURLConnection conn = null;
34
35 public JSONArray getBaiduRelateWord(String input) {
36 String t = String.valueOf(System.currentTimeMillis());
37 String response = null;
38 List<BaiduSuggestionUtil> list = new ArrayList<BaiduSuggestionUtil>();
39 try {
40 URL url = new URL(BAIDU_HOST + QUERY_PATH
41 + URLEncoder.encode(input, "utf-8") + PARAMETER + t);
42 conn = (HttpURLConnection) url.openConnection();
43 conn.setRequestProperty(REFERER_HEADER, REFERER);
44 in = conn.getInputStream();
45 inr = new InputStreamReader(in, "gbk");
46 int c = 0;
47 StringBuffer sb = new StringBuffer();
48 while ((c = inr.read()) != -1) {
49 sb.append((char) c);
50 }
51 response = sb.toString();
52 Pattern pattern = Pattern.compile(BAIDU_SUG_REG);
53 Matcher m = pattern.matcher(response);
54 while (m.find()) {
55 BaiduSuggestionUtil bd = new BaiduSuggestionUtil();
56 bd.setName(m.group().replace("\"", ""));
57 if(!bd.getName().equals(input)){
58 list.add(bd);
59 System.out.println(m.group().replace("\"", ""));
60 }
61 }
62 } catch (MalformedURLException e) {
63 e.printStackTrace();
64 return null;
65 } catch (UnsupportedEncodingException e) {
66 e.printStackTrace();
67 return null;
68 } catch (IOException e) {
69 e.printStackTrace();
70 return null;
71 } finally {
72 try {
73 if (inr != null) {
74 inr.close();
75 }
76 if (in != null) {
77 in.close();
78 }
79 } catch (IOException e) {
80 e.printStackTrace();
81 return null;
82 }
83 }
84 JSONArray jsonArray = JSONArray.fromObject(list);
85 return jsonArray;
86 }
87 public static void main(String args[]){
88 new BaiduSuggestionUtil().getBaiduRelateWord("zhongqiu");
89 }
90 /**
91 * 百度联想词
92 */
93 private String name;
94
95 public String getName() {
96 return name;
97 }
98
99 public void setName(String name) {
100 this.name = name;
101 }
102 }

  用工具类返回一个json格式数据,然后再action中调用这个json就行了。

下面是action中代码

public String findSuggestioName(){
JSONArray jsonArray
= baiduSuggestionUtil.getBaiduRelateWord(name);
String result
= jsonArray.toString();
getResponse().setContentType(
"text/json;charset=UTF-8");
try {
getResponse().getWriter().write(result);
}
catch (IOException e) {
e.printStackTrace();
}
return null;
}

 这是demo baidu.jsp

 1 <HEAD>
2 <base target="_self">
3 <meta http-equiv="pragma" content="no-cache">
4 <meta http-equiv="cache-control" content="no-cache">
5 <meta http-equiv="expires" content="0">
6 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
7 <TITLE>百度联想词</TITLE>
8 <link rel="icon" href="<%=request.getContextPath()%>/favicon.ico" type="image/x-icon" />
9 <link rel="shortcut icon" href="<%=request.getContextPath()%>/favicon.ico" type="image/x-icon" />
10 <link rel="stylesheet" type="text/css" href="<%=request.getContextPath()%>/pages/js/autocomplete/jquery.autocomplete.css"/>
11 <script type="text/javascript" src="<%=request.getContextPath()%>/pub/js/jquery-1.4.2.min.js"></script>
12 <script type="text/javascript" src="<%=request.getContextPath()%>/pages/js/autocomplete/jquery.autocomplete.js"></script>
13 <script>
14 $(document).ready(function() {
15 $("#suggestionName").autocomplete('<%=request.getContextPath() %>/findSuggestioName.action', {
16 matchContains: true,
17 minChars: 1,
18 extraParams: {name:function(){return $('#suggestionName').val();}},
19 dataType: "json",
20 mustMatch:false,
21 parse: function(data) {
22 return $.map(data, function(row) {
23 return {
24 data: row,
25 value: row.name,
26 result: row.name
27 }
28 });
29 },
30 formatItem: function(item) {
31 return item.name;
32 }
33 }).result(function(e, item) {
34 });
35 });
36
37 </script>
38 </HEAD>
39 <BODY>
40 <form name="siteform" action="" method="post" id="siteform">
41 <table width="100%" height="500" border="0" cellpadding="0" cellspacing="0">
42 <tr>
43 <td width="973" height="500" valign="top"><table border="0" cellpadding="0" cellspacing="0" class="section-content">
44
45 <tr>
46 <td valign="top"><table border=0 align="center" cellpadding=2 cellspacing=1>
47 <TBODY>
48
49
50 <TR>
51 <TD align="right">百度联想词:</TD>
52 <TD><input type="text" name="suggestionName" id="suggestionName"/>
53 </TD>
54 </TR>
55
56 </TBODY>
57 </TABLE></td>
58 </tr>
59 </table> </td>
60 </tr>
61 </table>
62 </form>
63 </BODY>
64 </HTML>

  需要用到的jar包,第一次来博客园,不知道怎么上传文件(智商啊!!!),就贴个图片吧!

 

ps:jquery-autocomplete对支持火狐有点问题,就是在中文输入法中,需要多按一次键才有提示效果,这个bug已经解决,网上有就不贴了。

还有就是当你选中下拉列表某一行时,文本框不会显示你选中的那一行,这是jquery-autocomplete 一个bug,已经调好

解决办法:

只要在jquery.autocomplete.js moveSelect(step)方法第333行处添加一行代码即可

 input.value=activeItem.text();

这是添加前的代码

 1 function moveSelect(step) {
2 listItems.slice(active, active + 1).removeClass(CLASSES.ACTIVE);
3 movePosition(step);
4 var activeItem = listItems.slice(active, active + 1).addClass(CLASSES.ACTIVE);
5 if(options.scroll) {
6 var offset = 0;
7 listItems.slice(0, active).each(function() {
8 offset += this.offsetHeight;
9 });
10 if((offset + activeItem[0].offsetHeight - list.scrollTop()) > list[0].clientHeight) {
11 list.scrollTop(offset + activeItem[0].offsetHeight - list.innerHeight());
12 } else if(offset < list.scrollTop()) {
13 list.scrollTop(offset);
14 }
15 }
16 };

这是添加后的代码

 1 function moveSelect(step) {
2 listItems.slice(active, active + 1).removeClass(CLASSES.ACTIVE);
3 movePosition(step);
4 var activeItem = listItems.slice(active, active + 1).addClass(CLASSES.ACTIVE);
5 input.value=activeItem.text();
6 if(options.scroll) {
7 var offset = 0;
8 listItems.slice(0, active).each(function() {
9 offset += this.offsetHeight;
10 });
11 if((offset + activeItem[0].offsetHeight - list.scrollTop()) > list[0].clientHeight) {
12 list.scrollTop(offset + activeItem[0].offsetHeight - list.innerHeight());
13 } else if(offset < list.scrollTop()) {
14 list.scrollTop(offset);
15 }
16 }
17 };

这是最终的demo效果。选中某一行,文本框随之变化。

第一次写blog,记录下,坚持!

 

 

 

 

 

posted @ 2011-09-04 19:21  montya  阅读(4447)  评论(7编辑  收藏  举报