- 浏览: 887309 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (687)
- java (127)
- servlet (38)
- struts (16)
- spring (22)
- hibernate (40)
- javascript (58)
- jquery (18)
- tomcat (51)
- 设计模式 (6)
- EJB (13)
- jsp (3)
- oracle (29)
- RUP (2)
- ajax (3)
- java内存管理 (4)
- java线程 (12)
- socket (13)
- path (5)
- XML (10)
- swing (2)
- UML (1)
- JBPM (2)
- 开发笔记 (45)
- Note参考 (15)
- JAXB (4)
- Quartz (2)
- 乱码 (2)
- CSS (2)
- Exception (4)
- Tools (7)
- sqlserver (3)
- DWR (7)
- Struts2 (47)
- WebService (2)
- 问题解决收藏 (7)
- JBOSS (7)
- cache (10)
- easyUI (19)
- jQuery Plugin (11)
- FreeMarker (6)
- Eclipse (2)
- Compass (2)
- JPA (1)
- WebLogic (1)
- powerdesigner (1)
- mybatis (1)
最新评论
-
bugyun:
受教了,谢谢
java 正则表达式 过滤html标签 -
xiongxingxing_123:
学习了,感谢了
java 正则表达式 过滤html标签 -
wanmeinange:
那如果无状态的。对同一个任务并发控制怎么做?比如继承Quart ...
quartz中参数misfireThreshold的详解 -
fanjieshanghai:
...
XPath 元素及属性查找 -
tianhandigeng:
还是没明白
quartz中参数misfireThreshold的详解
在做商务E流量分析的时候,需要实现一个功能:如果访客是通过搜索引擎的搜索找到客户网站的,要统计出访客是通过哪个搜索引擎访问到页面,并且统计出是通过 什么关键字搜索到该网站的。在网上google一下,发出对这方面的描述文档还是比较少的,在做这个功能的过程中有些经验给人家分享一下。
实现这样的功能,基本原理是获取到来源地址,然后分析其中的内容,把所需要的搜索引擎名称和关键字取出。
获取来源地址很简单,在servlet 中可以通过HttpServletRequest.getHeader("Referer")方法取得,jsp页面中可以通过 request.getHeader("referer")取得。取得来源地址后便可以通过分析得到的来源地址分析出我们所需要的内容。通常我们常用的搜 索引擎有以下14个。
http://www.google.com;
http://www.google.cn;
http://www.sogou.com;
http://so.163.com;
http://www.iask.com;
http://www.yahoo.com;
http://www.baidu.com;
http://www.3721.com;
http://www.soso.com;
http://www.zhongsou.com;
http://www.alexa.com;
http://www.search.com;
http://www.lycos.com;
http://www.aol.com;
要获取我们所需要的内容,我们必须分析 各个引擎的特性,由于各个搜索引擎的格式不一样,获取到的来源地址必然也不一致,下面我们来分析一下各种搜索引擎的地址格式。
在搜索引擎里输入关键字,点击搜索之后地址栏中的内容就是我们通过HttpServletRequest.getHeader("Referer")或 request.getHeader("referer")取得的来源地址。
google搜索引擎:
http://www.google.com/search?hl= zh-N&newwindow=1&
q=%E4%BB%8A%E7%A7%91%E4%BF%A1%E6%81%AF%E7%A7%91%E6%8A%80&
btnG= %E6%90%9C%E7%B4%A2&lr=
http://www.google.cn/search?hl= zh-N&newwindow=1&
q=%E6%B0%B8%E5%AE%89%E8%B7%AF%E7%81%AF&
btnG= %E6%90%9C%E7%B4%A2&meta=
从这里我们可以得到我们所需要的搜索引擎名称和关键字。其中,搜索引擎显而易见,是google;而关键字呢?经过我仔细观察、
测试后发现关键字是编码后放 在参数q里,也就是说
%E4%BB%8A%E7%A7%91%E4%BF%A1%E6%81%AF%E7%A7%91%E6%8A%80和
%E6%B0 %B8%E5%AE%89%E8%B7%AF%E7%81%AF
就是输入的关键字。
(有人会问,那btnG这个参数的值是什么来头,他也编过码 啊?是用来干嘛的呢?呵呵,它什么来头都没有,什么也没干,多余的!你试试输入关键字之后点击搜索按钮看看地址栏,然后再试试输入关键字之后回车,再看看 地址栏,看出两种做法在地址栏中的一点点差别之后你就会明白的啦)
baidu搜索引擎:
(1)http://www.baidu.com/s?ie=gb2312&bs=%CB%B3%B5%C2%BC%D2%BE%DF&sr=&z=&cl=3&f=8&
wd=%BD%F1%BF%C6%BF%C6%BC%BC&ct=0
(2)http://www.baidu.com/baidu?tn=nanlingcb&word=%CB%B3%B5%C2%BC%D2%BE%DF
baidu 搜索引擎,这里需要说明一下,当我们在通过在http://www.baidu.com中 输入搜索关键字,获取的来源地址为(1)字符串;当通过其它方式,比如在一些浏览器插件中输入关键字搜索的获取的来源地址为(2)字符串。通过获取来的这来源地,我也可以很容易的知道当前的搜索引擎是baidu;而关键字呢?看看(1),这里有两个经过编码的字符串,到底哪个是关键字呢?wd的值是关键字!信我啦!那bs的值是什么呢?你输入关键字多搜索几次,看看你有什么发现?发现了吧,bs是你上一次搜索的关键字!这个我们不管,它不是我们所要的东 西。分析得知,在baidu搜索引擎里有两个地方放关键字,一个地方是编码后放在在参数wd里,另外一个地方是编码后放在word参数里。明白了吧?:)
sogou搜索引擎
http://www.sogou.com/web?query=%BD%F1%BF%C6%D0%C5%CF%A2%BF%C6%BC%BC
这个就没这么复杂了,我们通过字符串可以知道搜索引擎为sogou,关键字经编码后放在参数query里,这里值为
%BD%F1%BF%C6%D0%C5 %CF%A2%BF%C6%BC%BC,有时候也会附带多一些参数,但附带的这些参数对我们来说是没用的。
163搜索引擎
http://cha.so.163.com/so.php?in=seek&c=26&key=032152284&q=%BD%F1%BF%C6%D0%C5%CF%A2%BF%C6%BC%BC
&x=61&y=19
这个也不复杂,分析得知,搜索引擎名称为163,关键字在参数q里,这里值为%BD%F1%BF%C6%D0%C5%CF%A2%BF%C6%BC%BC
yahoo 搜索引擎
http://search.cn.yahoo.com/search?p=%D3%C0%B0%B2%C2%B7%B5%C6&
source=toolbar_yassist_button&pid=58061_1006&ei=gbk
http://search.cn.yahoo.com/search?lp=%E4%B8%AD%E5%B1%B1%E5%8F%A4%E9%95%87%E7%81%AF%E9%A5%B0&
p=%E4%BB%8A%E7%A7%91%E4%BF%A1%E6%81%AF%E7%A7%91%E6%8A%80&pid=&ei=UTF-8
很容易得到,搜索引擎名称为yahoo,那关键字是哪些呢?关键字是放在参数p里,而参数lp的值跟baidu类似,也是上一次搜索的关键字。
lycos 搜索引擎
http://search.lycos.com/?query=website
这 个我们用得比较少,同样我们通过这个字符串得出搜索引擎为lycos,关键字放在query里.
3721搜索引擎
http://seek.3721.com/index.htm?name=%D6%E9%BA%A3%CF%E3%D6%DE%C0%CD%CE%F1%CA%D0%B3%A1
容 易得到,搜索引擎名称为3721,关键字放在name里
search搜索引擎
http://www.search.com/search?lq=d%25E4%25B8%25AD%25E5%259B%25BDd&
q=%E4%B8%AD%E5%8D%8E%E4%BA%BA%E6%B0%91%E5%85%B1%E5%9B%BD%E5%92%8C
这 个我们用得很少,也容易得到搜索引擎名称为search,关键字放在p里,而lp放的是什么呢?尚未弄清楚,
反正与我们所要的东西无关。
soso 搜索引擎
http://www.soso.com/q?w=%BD%F1%BF%C6%D0%C5%CF%A2%BF%C6%BC%BC12&sc=web&
bs=%BD%F1%BF%C6%D0%C5%CF%A2%BF%C6%BC%BC1&ch=w.soso.pr&uin=&lr=chs&web_options=on
可 以看出搜索引擎名称为soso,关键字放在参数w里,需参数bs的值跟baidu相似,是上一次搜索的关键字
zhongsou搜索引擎
http://p.zhongsou.com/p?w=%BD%F1%BF%C6%D0%C5%CF%A2%BF%C6%BC%BC&l=&jk=&k=&r=&aid=&pt=1&dt=2
可 以看出搜索引擎名称为zhongsou,关键字在参数w里。
alexa搜索引擎
http://www.alexa.com/search?q=%E4%BB%8A%E7%A7%91%E4%BF%A1%E6%81%AF%E7%A7%91%E6%8A%80
得出搜索引擎名称为zhongsou,关键字放在参数q里。
对各种搜索引擎的url的分析已完成,大家都对这些常用的搜索引擎的url的格式有所了解了,下面我们看看怎样从我们所取得的这些字符串中得到我们所要的信息,也就是怎样从这些字符串中提取我们所需的搜索引擎名称和搜索关键字.这里理所当然使用功能强大的正则表达式了.好,现在我们逐个逐个地分析各个搜索引擎用什么正则表达式提取我们所需要的内容.
首先还是先分析 google搜索引擎:
上面已经提到我们取得的google搜索引擎的地址是这样的:
http://www.google.com/search?hl= zh-N&newwindow=1
&q=%E4%BB%8A%E7%A7%91%E4%BF%A1%E6%81%AF%E7%A7%91%E6%8A%80&
btnG= %E6%90%9C%E7%B4%A2&lr=
http://www.google.cn/search?hl= zh-N&newwindow=1
&q=%E6%B0%B8%E5%AE%89%E8%B7%AF%E7%81%AF&
btnG= %E6%90%9C%E7%B4%A2&meta=
其 实它还有一种形式是这样的:
(3)http://www.google.com/custom?hl=zh-CN&inlang=zh-CN&ie=GB2312&oe=GB2312&newwindow=1&
client=pub3261928361684765&cof=FORID%3A1%3BGL%3A1%3BBGC%3AFFFFFF%3BT%3A%23000000%3BLC%3A
%230000ff%3BVLC%3A%23663399%3BALC%3A%230000ff%3BGALT%3A%23008000%3BGFNT%3A
%230000ff%3BGIMP%3A%230000ff%3BDIV%3A%23336699%3BLBGC%3A336699%3BAH%3Acenter%3B
&q=%C5%B7%C2%FC%D5%D5%C3%F7&lr=
OH,my god,是不是看得头晕了?先不要晕,往下看你就不会觉得晕的啦....
我们仔细观察一下,这三种格式都有一个共通点,大家有没有发现呢?就是 他的格式都是这样的:
http://www.google.[...]/[...]&q= [关键字][...]
[...]表示有一个以上的字符.
就如(2)我们在里面放入一些[]就可以看得更清楚了:
http://www.google.[cn]/[search?hl=zh-CN&newwindow=1]
&q=[%E6%B0%B8%E5%AE%89%E8%B7%AF%E7%81%AF][&btnG=%E6%90%9C%E7%B4%A2&meta=]
看明白了吧?看明白了我们就接下去了.于是我们可以得出google搜索引擎的正则表达式了:
http:\\/\\/www\\.google \\.[a-zA-Z]+\\/.+[\\&\\?]q=[^\\&]*。
现在解释一下这个正则表达式的意思。
http:\\/ \\/www\\.这一段是匹配http://www.,为什么这里多了这么多\呢?因为字符 '/'和字符'.'在正则表达式中有特殊意义,要用'\'对这两个字符转义,'/'通过'\/'转义,相似的.也通过'\.'转义,而字符'\'在 java里也是一个特殊字符,本身也需要转义,所以'\/'写成'\\/',类似的'\.'写成'\\.';
接下来google\\.[a-zA-Z]+ \\/.+匹配google.com/search?hl=zh-CN&newwindow=1,这里解释一下[a-zA-Z]+,意思是最少有 一个(包括一个)以上英文字母,[a-zA-Z]表示从a到z,从A到Z的字符,+表示至少一个以上,[\\&\\?]q=[^\\&]*匹配的是&q=%E6%B0%B8%E5%AE%89%E8%B7%AF%E7%81%AF,[\\&\\?],表示字符&或字符?由于&和?都是特殊字符,所以都要用转义符转义,q=[^\\&]*表示q=后面是零个(包括零个)以上的非& 字符,[^\\&]表示不为&的字符,为什么不为&呢,因为&后面的字符也经不再属于参数q的值了,我们要取的是q=之 后,字符&之前的字符串.这个正则表达式的解释就到此了。现在这个正则表达式已经可以从众多的获取过来的来源地址中分辩出哪些是google搜索引擎了,但是有一个问题,假如以后google搜索引擎不是这样,换成http://search.google.com/search?hl=zh-CN&newwindow=1&q=%E6%B0%B8%E5%AE%89%E8%B7%AF%E7%81%AF
&btnG=%E6%90%9C%E7%B4%A2&meta= 呢,
那这个正则表达式就不合适了,怎样能在以后改动之后我们写的正则表达式还适用呢?很简单,我们把它改成这个样子:\\.google\\.[a- zA-Z]+\\/.+[\\&\\?]q=[^\\&]*,意思是我们不必匹配http://www这 一串字符串。这样如果google搜索引擎做了类似http://search.google.com/..... 的修改,我们写的正则表达式也适用了,那假如它把域名也改了就没得说了,:);还有一种情况,在地址栏里输入www.google.com:80/也可以正常访问google,也就是说还有 一种情况就是加端口的访问,这种情况也要考虑到,因此之前我们的正则表达式应改成:\\.google\\.[a-zA-Z]+(:\\d{1,}){0,1}\\/.+[\\&\\?]q=[^\\&]*, (:\\d{1,}){0,1}是什么意思呢?他匹配类似":80"也就是说冒号(:)后跟1个以上的数字字符,而端口是可选的,并且如果出现只会出现一 次,所以用{0,1}.这个正则表达式的用途是用于获取关键字,所以这里我把关键字部分划分为一个组(这在下面会用到),因此,最终的正则表达式为:
\\.google\\.[a-zA-Z]+(:\\d{1,}){0,1}\\/.+[\\&\\?]q=([^\\&]*)
对 google搜索引擎已经说得很详细,接下来的我就简略的说说了,原理都差不多的了。
baidu搜索引擎:
分 析得知baidu搜索引擎的正则表达式为:
\\.baidu\\.[a-zA-Z]+(:\\d{1,}){0,1}\\/.+[\\&\\?]wd=([^\\&]*) 或
\\.baidu\\.[a-zA-Z]+(:\\d{1,}){0,1}\\/.+[\\&\\?]word=([^\\&]*)
sogou 搜索引擎
http://www.sogou.com/web?query=%BD%F1%BF%C6%D0%C5%CF%A2%BF%C6%BC%BC
正 则表达式:
\\.sogou\\.[a-zA-Z]+(:\\d{1,}){0,1}\\/.+[\\&\\?]query=([^\\&]*)
yahoo搜索引擎
正 则表达式:
\\.yahoo\\.[a-zA-Z]+(:\\d{1,}){0,1}\\/.+[\\&\\?]p=([^\\&]*)
lycos 搜索引擎
http://search.lycos.com/?query=website
正 则表达式:
\\.lycos\\.[a-zA-Z]+(:\\d{1,}){0,1}\\/.*[\\&\\?]query=([^\\&]*)
3721 搜索引擎
http://seek.3721.com/index.htm?name=%D6%E9%BA%A3%CF%E3%D6%DE%C0%CD%CE%F1%CA%D0%B3%A1
http://seek.3721.com/index.htm?q=%D6%E9%BA%A3%CF%E3%D6%DE%C0%CD%CE%F1%CA%D0%B3%A1
正 则表达式:
\\.3721\\.[a-zA-Z]+(:\\d{1,}){0,1}\\/.+[\\&\\?]p=([^\\&]*) 或
\\.3721\\.[a-zA-Z]+(:\\d{1,}){0,1}\\/.+[\\&\\?]name=([^\\&]*)
search 搜索引擎
正则表达式:
\\.search\\.[a-zA-Z]+(:\\d{1,}){0,1}\\/.+[\\&\\?]q=([^\\&]*)
soso搜索引擎
正 则表达式:
\\.soso\\.[a-zA-Z]+(:\\d{1,}){0,1}\\/.+[\\&\\?]w=([^\\&]*)
zhongsou搜索引擎
http://p.zhongsou.com/p?w=%BD%F1%BF%C6%D0%C5%CF%A2%BF%C6%BC%BC&l=&jk=&k=&r=&aid=&pt=1&dt=2
正 则表达式:
\\.zhongsou\\.[a-zA-Z]+(:\\d{1,}){0,1}\\/.+[\\&\\?]w=([^\\&]*)
alexa搜索引擎
http://www.alexa.com/search?q=%E4%BB%8A%E7%A7%91%E4%BF%A1%E6%81%AF%E7%A7%91%E6%8A%80
正 则表达式:
\\.alexa\\.[a-zA-Z]+(:\\d{1,}){0,1}\\/.+[\\&\\?]q=([^\\&]*)
iask搜索引擎
正则表达式:
\\.iask\\.[a-zA-Z]+(:\\d{1,}){0,1}\\/.+[\\&\\?]k=([^\\&]*) 或
\\.iask\\.[a-zA-Z]+(:\\d{1,}){0,1}\\/.+[\\&\\?]_searchkey=([^\\&]*)
好了,正则表达式已经写出来了,事情已经完成一半了。现在我们把话题转一下,等会我们再转回来,现在我们先看看如何获取搜索引擎的名称。同样,也 需要用正则表达式,正则表达式实在太强了:)。
我们可以通过以下的正则表达式匹配到google搜索引擎:
http:\\/\\/.* \\.google\\.com(:\\d{1,}){0,1}\\/或
http:\\/\\/.*\\.google\\.cn(:\\d{1,}){0,1}\\/
类 似的也可以匹配其它搜索引擎,我把他们写在一起:
http:\\/\\/.*\\.(google\\.com(:\\d{1,}){0,1}\\/|google\\.cn(:\\d{1,}){0,1}\\/|
baidu\\.com(:\\d{1,}){0,1}\\/|yahoo\\.com(:\\d{1,}){0,1}\\/|
iask\\.com(:\\d{1,}){0,1}\\/|sogou\\.com(:\\d{1,}){0,1}\\/|
163\\.com(:\\d{1,}){0,1}\\/|lycos\\.com(:\\d{1,}){0,1}\\/|
aol\\.com(:\\d{1,}){0,1}\\/|3721\\.com(:\\d{1,}){0,1}\\/|
search\\.com(:\\d{1,}){0,1}\\/|soso.com(:\\d{1,}){0,1}\\/|
zhongsou\\.com(:\\d{1,}){0,1}\\/|alexa\\.com(:\\d{1,}){0,1}\\/)
通过以下程序可以获取到搜索引擎的名称:
import java.util.regex.*; public class GetEngine { public static void main(String[] arg) { GetEngine engine=new GetEngine(); String referer="http://www.baidu.com/s?wd=java%D1%A7%CF%B0%CA%D2"; String engineName=engine.getSearchEngine(referer); System.out.println("搜索引擎名称:"+engineName); } public String getSearchEngine(String refUrl) { if(refUrl.length()>11) { //p是匹配各种搜索引擎的正则表达式 Pattern p = Pattern.compile("http:\\/\\/.*\\.(google\\.com(:\\d{1,}){0,1}\\/| google\\.cn(:\\d{1,}){0,1}\\/|baidu\\.com(:\\d{1,}){0,1}\\/| yahoo\\.com(:\\d{1,}){0,1}\\/|iask\\.com(:\\d{1,}){0,1}\\/| sogou\\.com(:\\d{1,}){0,1}\\/|163\\.com(:\\d{1,}){0,1}\\/| lycos\\.com(:\\d{1,}){0,1}\\/|aol\\.com(:\\d{1,}){0,1}\\/| 3721\\.com(:\\d{1,}){0,1}\\/|search\\.com(:\\d{1,}){0,1}\\/| soso.com(:\\d{1,}){0,1}\\/|zhongsou\\.com(:\\d{1,}){0,1}\\/| alexa\\.com(:\\d{1,}){0,1}\\/)"); Matcher m = p.matcher(refUrl); if (m.find())//如果来源地址可以匹配以上的pattern { //因为m.group(0)是域名,m.group(1)才是我们最合适我们所要的 return insteadCode(m.group(1),"(\\.com(:\\d{1,}){0,1}\\/|\\.cn(:\\d{1,}){0,1}\\/| \\.org(:\\d{1,}){0,1}\\/)","");//把.com,.cn,.org替换为"" } } return "未发现搜索引擎"; } public String insteadCode(String str,String regEx,String code){ Pattern p=Pattern.compile(regEx); Matcher m=p.matcher(str); String s=m.replaceAll(code); return s; } }
通过以上的代码即可得出搜索引擎名称了,似乎任务完成一大半了。只是接着下来的要做的事情比之前所做的要麻烦点点,麻烦就麻烦在编码上。
现在我样回过头看我们上面写的一大堆各种搜索引擎的正则表达式。
由于这里要大量的字符串操作,这里使用StringBuffer来做字符串的连接。
StringBuffer sb=new StringBuffer();
sb.append("\\.google\\.[a-zA-Z]+(:\\d{1,}){0,1}\\/.+[\\&\\?]q=([^\\&]*)")
.append("|\\.iask\\.[a-zA-Z]+(:\\d{1,}){0,1}\\/.+[\\&\\?]k=([^\\&]*)")
.append("|\\.iask\\.[a-zA-Z]+(:\\d{1,}){0,1}\\/.+[\\&\\?]_searchkey=([^\\&]*)")
.append("|\\.sogou\\.[a-zA-Z]+(:\\d{1,}){0,1}\\/.+[\\&\\?]query=([^\\&]*)")
.append("|\\.163\\.[a-zA-Z]+(:\\d{1,}){0,1}\\/.+[\\&\\?]q=([^\\&]*)")
.append("|\\.yahoo\\.[a-zA-Z]+(:\\d{1,}){0,1}\\/.+[\\&\\?]p=([^\\&]*)")
.append("|\\.baidu\\.[a-zA-Z]+(:\\d{1,}){0,1}\\/.+[\\&\\?]wd=([^\\&]*)")
.append("|\\.baidu\\.[a-zA-Z]+(:\\d{1,}){0,1}\\/.+[\\&\\?]word=([^\\&]*)")
.append("|\\.lycos\\.[a-zA-Z]+(:\\d{1,}){0,1}\\/.*[\\&\\?]query=([^\\&]*)")
.append("|\\.aol\\.[a-zA-Z]+(:\\d{1,}){0,1}\\/.+[\\&\\?]encquery=([^\\&]*)")
.append("|\\.3721\\.[a-zA-Z]+(:\\d{1,}){0,1}\\/.+[\\&\\?]p=([^\\&]*)")
.append("|\\.3721\\.[a-zA-Z]+(:\\d{1,}){0,1}\\/.+[\\&\\?]name=([^\\&]*)")
.append("|\\.search\\.[a-zA-Z]+(:\\d{1,}){0,1}\\/.+[\\&\\?]q=([^\\&]*)")
.append("|\\.soso\\.[a-zA-Z]+(:\\d{1,}){0,1}\\/.+[\\&\\?]w=([^\\&]*)")
.append("|\\.zhongsou\\.[a-zA-Z]+(:\\d{1,}){0,1}\\/.+[\\&\\?]w=([^\\&]*)")
.append("|\\.alexa\\.[a-zA-Z]+(:\\d{1,}){0,1}\\/.+[\\&\\?]q=([^\\&]*)");
这个正则表达式是把所有搜索引擎用或"|"连接起来,因为只要匹配其中一个搜索引擎的正则表达式就可以。
前面已经说到,关键字是经过编码 的,我们直接取出的关键字会像%BD%F1%BF%C6%D0%C5%CF%A2%BF%C6%BC%BC12,
这样的关键字我们无法读懂,因些需要对这 些关键进行反编码,这要用到java.net.URLDecoder.decode(String s,String enc),这个方法有两个参数,一个参数是要进行反编码的字符串,另一个是指定的字符集。第一个参数很简单,只要我们把取得的关键放到这个参数里,至于第 二个参数怎样呢?这里我只讨论中文的情况,这些搜索引擎有两种字符集编码方式,一种是UTF-8,另外一种是GBK。
只有GBK一种编码方式的搜 索引擎:
3721,iask,sogou,163,baidu,soso,zhongsou
只有UTF-8一种编码方式的搜索引擎:
lycos,aol,search,alexa
有 两种编码方式的:
google,yahoo
只有一种编码方式的问题容易解决,有两种编码方式的怎办呢?办法总比问题多,其实采用哪一个编码方工,它是有”暗示“的,对于google,大多数情况下它是采用UTF-8的编码方式,我们在浏览器的地址栏上输入www.google.com搜索的都是以这种方式来编码的,但有种情况如:
http://www.google.com/custom?hl=zh-CN&inlang=zh-CN&ie=GB2312&oe=GB2312&newwindow=1&client=pub-3261928361684765&
cof=FORID%3A1%3BGL%3A1%3BBGC%3AFFFFFF%3BT%3A%23000000%3BLC%3A%230000ff
%3BVLC%3A%23663399%3BALC%3A%230000ff%3BGALT%3A%23008000%3BGFNT%3A%230000ff%3BGIMP%3A
%230000ff%3BDIV%3A%23336699%3BLBGC%3A336699%3BAH%3Acenter%3B&q=%C5%B7%C2%FC%D5%D5%C3%F7&lr=
这种情况下就不一定是UTF-8编码了,这种情况下以ie这个参数指定,这里ie=gb2312,所以编码方式为gb2312,而gb2312是gbk的字 集,所以这里我们用gbk而不用gb2312;对于yahoo情况类似,只不过yahoo在大多数情况下使用GBK编码,如:
http://search.cn.yahoo.com/search?p=%C5%B7%C2%FC%BF%C6%BC%BC%CA%B5%D2%B5
&source=toolbar_yassist_button&pid=54554_1006&f=A279_1
就是GBK编码,但这种情况:
http://search.cn.yahoo.com/search?ei=gbk&fr=fp-tab-web-ycn&source=errhint_up_web
&p=%BD%F1%BF%C6&meta=vl%3Dlang_zh-CN%26vl%3Dlang_zh-TW&pid=ysearch
就 用ei参数里指定的纺码方式了,这里有可能指定的是gbk,也有可能指定的是UTF-8。
根据以上的解释,于是有以下的程序来获得各种搜索引擎的关键字:
import java.util.regex.*; import java.sql.*; import java.net.URLDecoder; import java.io.*; public class GetKeyword { public static void main(String[] arg) { String referer="http://www.baidu.com/s?wd=java%D1%A7%CF%B0%CA%D2"; if(arg.length!=0) { referer=arg[0]; } GetKeyword getKeyword=new GetKeyword(); String searchEngine=getKeyword.getSearchEngine(referer); System.out.println("searchEngine:"+searchEngine); System.out.println("keyword:"+getKeyword.getKeyword(referer)); } public String getKeyword(String refererUrl) { StringBuffer sb=new StringBuffer(); if(refererUrl!=null) { sb.append("(google\\.[a-zA-Z]+/.+[\\&|\\?]q=([^\\&]*)") .append("|iask\\.[a-zA-Z]+/.+[\\&|\\?]k=([^\\&]*)") .append("|iask\\.[a-zA-Z]+/.+[\\&|\\?]_searchkey=([^\\&]*)") .append("|sogou\\.[a-zA-Z]+/.+[\\&|\\?]query=([^\\&]*)") .append("|163\\.[a-zA-Z]+/.+[\\&|\\?]q=([^\\&]*)") .append("|yahoo\\.[a-zA-Z]+/.+[\\&|\\?]p=([^\\&]*)") .append("|baidu\\.[a-zA-Z]+/.+[\\&|\\?]wd=([^\\&]*)") .append("|baidu\\.[a-zA-Z]+/.+[\\&|\\?]word=([^\\&]*)") .append("|lycos\\.[a-zA-Z]+/.*[\\&|\\?]query=([^\\&]*)") .append("|aol\\.[a-zA-Z]+/.+[\\&|\\?]encquery=([^\\&]*)") .append("|3721\\.[a-zA-Z]+/.+[\\&|\\?]p=([^\\&]*)") .append("|3721\\.[a-zA-Z]+/.+[\\&|\\?]name=([^\\&]*)") .append("|search\\.[a-zA-Z]+/.+[\\&|\\?]q=([^\\&]*)") .append("|soso\\.[a-zA-Z]+/.+[\\&|\\?]w=([^\\&]*)") .append("|zhongsou\\.[a-zA-Z]+/.+[\\&|\\?]w=([^\\&]*)") .append("|alexa\\.[a-zA-Z]+/.+[\\&|\\?]q=([^\\&]*)") .append(")"); Pattern p = Pattern.compile(sb.toString()); Matcher m = p.matcher(refererUrl); return decoderKeyword(m,refererUrl); } return null; } public String decoderKeyword(Matcher m,String refererUrl) { String keyword=null; String encode="UTF-8"; String searchEngine=getSearchEngine(refererUrl); if(searchEngine!=null) { if ((checkCode("3721|iask|sogou|163|baidu|soso|zhongsou",searchEngine) ||(checkCode("yahoo",searchEngine)&&!checkCode("ei=utf-8",refererUrl.toLowerCase())))) { encode = "GBK"; } if (m.find()) { for (int i = 2; i <= m.groupCount(); i++) { if (m.group(i) != null)//在这里对关键字分组就用到了 { try { keyword = URLDecoder.decode(m.group(i), encode); } catch(UnsupportedEncodingException e) { System.out.println(e.getMessage()); } break; } } } } return keyword; } public String getSearchEngine(String refUrl) { if(refUrl.length()>11) { //p是匹配各种搜索引擎的正则表达式 Pattern p = Pattern.compile("http:\\/\\/.*\\.(google\\.com(:\\d{1,}){0,1}\\/| google\\.cn(:\\d{1,}){0,1}\\/|baidu\\.com(:\\d{1,}){0,1}\\/| yahoo\\.com(:\\d{1,}){0,1}\\/|iask\\.com(:\\d{1,}){0,1}\\/| sogou\\.com(:\\d{1,}){0,1}\\/|163\\.com(:\\d{1,}){0,1}\\/| lycos\\.com(:\\d{1,}){0,1}\\/|aol\\.com(:\\d{1,}){0,1}\\/| 3721\\.com(:\\d{1,}){0,1}\\/|search\\.com(:\\d{1,}){0,1}\\/| soso.com(:\\d{1,}){0,1}\\/|zhongsou\\.com(:\\d{1,}){0,1}\\/| alexa\\.com(:\\d{1,}){0,1}\\/)"); Matcher m = p.matcher(refUrl); if (m.find()) { return insteadCode(m.group(1), "(\\.com(:\\d{1,}){0,1}\\/|\\.cn(:\\d{1,}){0,1}\\/|\\.org(:\\d{1,}){0,1}\\/)",""); } } return "未发现有搜索引擎"; } public String insteadCode(String str,String regEx,String code){ Pattern p=Pattern.compile(regEx); Matcher m=p.matcher(str); String s=m.replaceAll(code); return s; } public boolean checkCode(String regEx,String str){ Pattern p=Pattern.compile(regEx); Matcher m=p.matcher(str); return m.find(); } }
发表评论
-
java解决网站静态页面生成方案(源码)
2012-07-01 01:51 0提升网站性能的方式有很多,例如有效的使用缓存,生成静态页 ... -
Servlet映射的匹配原则,优先级
2012-06-08 22:45 1448一个元素用于映射一个已经注册的Servlet的一个对外访问 ... -
TOMCAT SESSION的持久化方法
2012-06-12 09:56 1284Tomcat5.5.12 实现Session持久化的配置: ... -
Servlet和filter的JAVAEE的配置
2012-06-05 22:52 881一、servlet容器对url的匹配过程: 当一个请求发送 ... -
tomcat 静态资源处理类DefaultServlet&Apache静态资源服务
2012-06-05 21:13 2321DefaultServlet是tomcat中用来处理静态资源和 ... -
RequestDispatcher接口中的include()方法和forward()方法的区别
2011-04-19 15:34 1165请求转发中 RequestDispatcher 接口中的 in ... -
文件上传下载(oreilly之MultipartReques)
2011-04-10 22:36 1240上传篇代码片段: import com.oreill ... -
使用jstl还要在web.xml里面配一下
2011-01-30 11:26 1935悲剧,有人说是不用apac ... -
JAVA WEB学习笔记(五)-自定义JSP标签
2011-01-27 13:28 815一、基本概念:********** ... -
Filter拦截include方式的请求
2010-12-16 12:15 1000最近需要在项目中做一个缓存框架,通过插件方式加入,要求可以 ... -
<转>web.xml 中的listener、 filter、servlet 加载顺序及其详解
2010-12-10 22:45 911转载自 ailongni 最终编 ... -
web.xml里listener、filter和servlet加载顺序和详解(二)
2010-12-10 22:44 1234相应元素配置 1、Web应用图标:指出IDE和GUI工具用来 ... -
转】servlet中web.xml配置详解(转)
2010-12-10 22:42 876转载自 limpid1215 最终编辑 limpid121 ... -
Tomcat6中启用invoker心得
2010-10-26 08:31 1578今天下了看了一下示例,TOMCAT6中启用invoker 访问 ... -
el表达式不起作用的解决方案
2010-10-12 14:18 872关键字: el表达式不起作用 今天晚上学习SSH,发现一个el ... -
getOutputStream() has already been called for this response
2010-10-11 16:15 1266java.lang.IllegalStateException ... -
关于serveletContext.getRealPath()方法
2010-10-11 10:23 20411.关于request.getRealPath 问 ... -
采用application/vnd.ms-excel导出excel时修改文件名
2010-09-26 10:17 3887设置response属性,如下 response.se ... -
HttpServletResponse addHeader 与 setHeader 区别
2010-09-09 19:09 3877setHeader(name,value) :如果Header ... -
web.xml配置详解
2010-09-09 09:47 744转自:http://blog.csdn.net/j ...
相关推荐
在PHP编程中,有时我们需要获取用户访问我们网站时...总的来说,`getKeywords()`函数提供了一种实用的手段来获取用户通过搜索引擎到达网站时所使用的关键字,从而帮助我们更好地理解用户需求,优化网站内容和SEO策略。
标题提到的“PHP获取搜索引擎关键字来源的函数”就是解决此类问题的一个实用方法。 这个函数的主要目的是从HTTP_REFERER头信息中提取用户访问时所用的搜索引擎关键字。HTTP_REFERER是服务器端获取用户上一个页面URL...
索引是搜索引擎的关键组成部分,通过预先分析和存储数据,使得搜索过程能够在短时间内完成。当用户输入关键词时,程序会快速地在索引中查找匹配项,而非逐条扫描所有数据,大大提升了搜索速度。 除了基本的搜索功能...
通过这个方法,我们不仅能获取到搜索引擎来源,还可以得到用户搜索的具体关键词,这对于网站流量分析和SEO优化来说非常有帮助。 在实现代码中,我们定义了一个search_word_from函数,该函数首先检查HTTP_REFERER...
其中,百度和谷歌等是目前市场上最知名的搜索引擎。 #### QSearch的设计与实现 ##### 为什么需要QSearch QSearch作为去哪儿网自主研发的搜索引擎,主要解决以下几个方面的问题: - **高性能需求**:面对海量数据...
"关键字搜索的历史日志文件.rar"是一个压缩包,其中包含了一个名为"search.txt"的文件,这很可能是某个搜索引擎或信息系统中关于用户搜索行为的日志数据。这类数据集对于理解用户需求、优化搜索算法以及进行市场研究...
"百度关键字分析工具"就是这样一个专门针对百度搜索引擎的工具,它为优化人员提供了丰富的功能,以深入理解关键词的潜力和竞争情况。 一、关键词分析的重要性 关键词分析是SEO策略的基础,它包括识别与业务相关的...
正确选择和使用关键字可以帮助搜索引擎理解网页内容,提高排名。关键词应该与网站主题紧密相关,避免过度优化(关键词堆砌),确保内容对用户友好。 四、注意事项 - **质量优于数量**:关注高质量的反向链接,而非...
通过优化关键字、内容、网站结构和链接等关键元素,SEO技术帮助搜索引擎更好地理解和识别网站的相关性和质量。 #### 10种最佳SEO技术 1. **排名和点击同时优化**: - 创建为受众提供有价值信息的内容。这不仅有助...
其中,尽管付费排名仍然是主要的收入来源,但SEO的重要性日益凸显,尤其是在北美地区,SEO开始在付费搜索引擎市场中占据一席之地。 在中国,尽管SEO初露头角,但还远未成为主流的网络营销服务。市场处于早期阶段,...
**SEO**(Search Engine Optimization)即搜索引擎优化,是指通过改善网站的内容、结构和技术方面,提高其在搜索引擎自然搜索结果中的排名,从而吸引更多目标流量的过程。SEO对于任何希望在网络上提升可见性和吸引...
本文深入探讨了GnetFtp搜索引擎的算法设计与实现,特别是其中涉及到的中文检索技术和分词技术。通过对比现有的搜索引擎,GnetFtp在某些方面表现出了独特的优势,同时也指出了未来可能的改进方向。 #### 一、GnetFtp...
搜索引擎的使用需要遵守一定的规则和原则,例如,需要选择合适的搜索引擎和关键字。 7. 文件的删除:文件的删除是信息技术的基本操作。文件的删除可以通过多种方式来实现,包括使用Delete键、Shift+Delete键、鼠标...
目录索引类搜索引擎采用人工方式采集和存储网络信息,并依靠手工为每个网站确定一个标题,并给出大概的描述,建立关键字索引,将其放入相应的类目体系中。 信息技术是指一切与信息的获取、加工、表达、交流、管理和...
这种机制借鉴了网络搜索引擎广告的竞价模式,通过竞拍关键词来决定广告的展示位置和费用,从而实现广告主和平台的双赢。 关键字拍卖的核心在于广告主根据关键词的预期收益进行出价。广告主预估某一关键词被点击后...
SEO(Search Engine Optimization)是搜索引擎优化的简称,是提升网站在搜索引擎自然搜索结果中的排名的一系列策略和技术。这个"SEO专用工作表文档集合"显然是一套用于协助SEO优化的工具,其中包含了各种关键的工作...
这通常用在搜索引擎返回的结果页面上,帮助用户在大量文本中迅速找到他们搜索的关键词。 2. JavaScript实现方式:通过编写JavaScript脚本代码,在客户端直接处理DOM(文档对象模型),查找搜索结果页上的关键词,...
这其中包括搜索引擎的运用、文献检索的方法以及有效的文献阅读和分析策略。在WK3的学习笔记中,这些主题得到了深入探讨。 首先,文献检索是现代信息社会的一项基本能力,包括获取、管理、分析和分享信息。搜索引擎...
作者认为,当前的图像搜索引擎大多通过以下两类方法来识别图像:自动查找图像档和人工干预找出图片。 对于图像搜索引擎的检索途径,作者认为关键词检索、内容-based检索、混合检索等方法都可以应用于图像搜索。其中...