`
gladstone
  • 浏览: 68575 次
  • 性别: Icon_minigender_1
  • 来自: 上海
最近访客 更多访客>>
社区版块
存档分类
最新评论

善用Referer变量 -- 针对搜索引擎来源用户的提示

阅读更多

  1. 前言
  2. 实现效果
  3. 实现思路
  4. Java编码实现
  5. 其他 

1 前言:

注意到不少站点都有这个功能(包括javaeye和pconline)。

就是从百度/谷歌等搜索页面点过来的用户可以看见页面下方有搜索帮助提示,如图:

ScreenShot012 

前一阵子给CTBA也加上了相关功能, 这里大致说说实现方法。 

2 实现效果:

百度搜索”扯谈 新闻风”

ScreenShot025

点击进入CTBA的网站, 页面底部显示提示

 

3 实现思路:

参考了这篇文章, 利用请求的referer头. 如果乃还不知道referer是什么的话, 点这里

  • 从referer头中取得来源页面的地址
  • 解析出查询关键词
  • 全文检索得出结果

首先必须分析referer, 知道url中哪部分是关键字。例如在baidu输入关键字"扯谈社",在搜索结果中访问你的网站,那么来源的url就是:http://www.baidu.com/s?wd=%B3%B6%CC%B8%C9%E7上面的url中,wd=%B3%B6%CC%B8%C9%E7就是关键字部分,其中%B3%B6%CC%B8%C9%E7是"扯谈社"编码后的字符串, 我们通过UrlDecode解码就可以得到原来用户输入了什么关键字访问了自己的网站, 一般的编程语言都提供了解码工具, Java里的是URLDecoder。

百度对关键字是使用GBK编码,不过有些网站比如谷歌使用的是UTF8编码,需要根据不同情况加以处理。

上面的参考文章列出各个搜索引擎的关键字,但是其实有很多已经是无效的(比如china的已经转为使用google的搜索服务),实际上还有效的列表如下(加上了后来的有道)

名称 关键字 编码
baidu wd/word GBK
sogou query GBK
yahoo p UTF-8
google q UTF-8
search.msn q UTF-8
youdao q/lq UTF-8
search.114.vnet.cn kw GBK

4 Java的编码实现:

贴点代码

(HttpUtils.java)

    /** 
     * 从当前请求得到请求来源 
     * 
     * @param request 
     * @return 
     */ 
    public static String getReferer(HttpServletRequest request) { 
        return request.getHeader("Referer"); 
    }

    /** 
     * #727 针对搜索引擎来源用户的提示 
     * 
     * 从某个url里面得到特定参数的值 
     * 
     * @param name 
     * @param url 
     * @return 
     */ 
    public static String getParameterFromUrl(String name, String url) { 
        if (!url.contains("?")) { 
            return ""; 
        } 
        String reval = ""; 
        url = url.substring(url.indexOf("?") + 1); 
        String[] pairs = url.split("&"); 
        for (String pair : pairs) { 
            if (pair.contains("=")) { 
                String pairName = pair.substring(0, pair.indexOf("=")); 
                if (name.equals(pairName)) { 
                    reval = pair.substring(pair.indexOf("=") + 1); 
                    return reval; 
                } 
            } 
        } 
        return reval; 
    }

    /** 
     * #727 针对搜索引擎来源用户的提示 
     * 
     * 根据url取得搜索关键词 
     * 
     * @param refererURL 
     *            request的来源url 
     * @return 
     */ 
    public static String getSearchKeyInRefererURL(String refererURL) { 
        String searchKey = ""; 
        if (StringUtils.isNotEmpty(refererURL)) { 
            try { 
                if (refererURL.contains("baidu.com")) { 
                    // wd/word 
                    searchKey = getParameterFromUrl("wd", refererURL); 
                    if (StringUtils.isEmpty(searchKey)) { 
                        searchKey = getParameterFromUrl("word", refererURL); 
                    } 
                    if (StringUtils.isNotEmpty(searchKey)) { 
                        searchKey = StringUtils.urlDecode(searchKey, 
                                StringUtils.ENCODE_GBK); 
                    } 
                } else if (refererURL.contains("sogou.com")) { 
                    // query 
                    searchKey = getParameterFromUrl("query", refererURL); 
                    if (StringUtils.isNotEmpty(searchKey)) { 
                        searchKey = StringUtils.urlDecode(searchKey, 
                                StringUtils.ENCODE_GBK); 
                    } 
                } else if (refererURL.contains("search.114.vnet.cn")) { 
                    // kw 
                    searchKey = getParameterFromUrl("kw", refererURL); 
                    if (StringUtils.isNotEmpty(searchKey)) { 
                        searchKey = StringUtils.urlDecode(searchKey, 
                                StringUtils.ENCODE_GBK); 
                    } 
                } else if (refererURL.contains("search.msn.com") 
                        || refererURL.contains("live.com")) { 
                    // q 
                    searchKey = getParameterFromUrl("q", refererURL); 
                    if (StringUtils.isNotEmpty(searchKey)) { 
                        searchKey = StringUtils.urlDecode(searchKey, null); 
                    } 
                } else if (refererURL.contains("yahoo.com") 
                        || refererURL.contains("yahoo.cn")) { 
                    // p 
                    searchKey = getParameterFromUrl("p", refererURL); 
                    if (StringUtils.isNotEmpty(searchKey)) { 
                        searchKey = StringUtils.urlDecode(searchKey, null); 
                    } 
                } else if (refererURL.contains("www.google")) { 
                    // q 
                    searchKey = getParameterFromUrl("q", refererURL); 
                    if (StringUtils.isNotEmpty(searchKey)) { 
                        searchKey = StringUtils.urlDecode(searchKey, null); 
                    } 
                } else if (refererURL.contains("www.youdao")) { 
                    // q or lq 
                    searchKey = getParameterFromUrl("q", refererURL); 
                    if (StringUtils.isEmpty(searchKey)) { 
                        searchKey = getParameterFromUrl("lq", refererURL); 
                    } 
                    if (StringUtils.isNotEmpty(searchKey)) { 
                        searchKey = StringUtils.urlDecode(searchKey, null); 
                    } 
                } 
            } catch (Exception e) { 
                log.error(e.getMessage()); 
                searchKey = ""; 
            } 
        } 
        return searchKey; 
    }

 

(SearchEngineHintFilter.java)

在请求过滤器里面取得关键字, 进行搜索:

public void doFilter(ServletRequest request, ServletResponse response, 
            FilterChain chain) {

String refererURL = HttpUtils.getReferer(request); 

String searchKey = HttpUtils.getSearchKeyInRefererURL(refererURL); 
            if (StringUtils.isNotEmpty(searchKey)) { 
                log.debug("Got searchkey: " + searchKey+" |"+HttpUtils.getURL(httpRequest)); 
                httpRequest.setAttribute(WebConstants.REQUEST_SEARCH_KEYWORD, 
                        searchKey); 
                List<Map<String, String>> refTopics = doSearch(searchKey); 
                httpRequest.setAttribute(WebConstants.REQUEST_SEARCH_RESULT, 
                        refTopics); 
            }

}   

doSearch方法里面调用了庖丁分词, 根据关键字全文检索站内文章 

5 其他:

提示框的CSS+JS置底 这个详情请mockee来八卦

0
0
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics