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

本文介绍了一种从搜索引擎来源抓取用户关键词的方法,并提供了Java实现代码。通过对referer头的解析,可以获取并解码用户搜索关键词,进而实现针对搜索引擎用户的个性化提示。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  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的搜索服务),实际上还有效的列表如下(加上了后来的有道)

名称关键字编码
baiduwd/wordGBK
sogouqueryGBK
yahoopUTF-8
googleqUTF-8
search.msnqUTF-8
youdaoq/lqUTF-8
search.114.vnet.cnkwGBK

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来八卦

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值