2012年6月20日星期三

获得来自搜索引擎的关键字

一般情况下通过关键词进入的页面都是用户想要的内容,对于某些搜索搜录与关键词相关度不是很高的页面(例如列表页),我们需要根据用户搜索的关键词对用户进行引导,从而提高用户的体验,也可以提高网页的PV。

本文的原理是通过获取来源页面,分析来源URL的结构,提取出关键字,这些都是比较简单的东西。本文阐述重点是如何区分出几种常见的URL编码方式,然后进行相应的解码。因为应用是在ASP中进行,因此本文若有代码相关的例子,均是在ASP下调试通过的。其他语言下思想相同,且实现相对简单些。

提取各个搜索引擎的关键字

现在的各大搜索引擎全是基于GET请求方式的,即在URL后面带有一串参数。例如:我搜索“秋寒博客”

谷歌:http://www.google.cn/search?sourceid=navclient&hl=zh-CN&ie=UTF-8&rlz=1T4GGLL_zh-CN___CN352&q=%e7%a7%8b%e5%af%92%e5%8d%9a%e5%ae%a2

百度:http://www.baidu.com/s?wd=%C7%EF%BA%AE%B2%A9%BF%CD

必应:http://cn.bing.com/search?q=%E7%A7%8B%E5%AF%92%E5%8D%9A%E5%AE%A2&form=QBLH&filt=all

谷歌和Google的 q=%e7%a7%8b%e5%af%92%e5%8d%9a%e5%ae%a2 ,百度的 wd=%C7%EF%BA%AE%B2%A9%BF%CD ,必应的 q=%E7%A7%8B%E5%AF%92%E5%8D%9A%E5%AE%A2 中带下划线部分就是关键词。 其他搜索引擎也大致相同,通过URL就可以看出关键词的字段是哪个,然后可以通过正则将关键词提出。

提取主流搜索关键词的正则如下:

(?:yahoo.+?[\?|&]p=|openfind.+?query=|google.+?q=|lycos.+?query=|onseek.+?keyword=|search\.tom.+?word=|search\.qq\.com.+?word=|zhongsou\.com.+?word=|search\.msn\.com.+?q=|yisou\.com.+?p=|sina.+?word=|sina.+?query=|sina.+?_searchkey=|sohu.+?word=|sohu.+?key_word=|sohu.+?query=|163.+?q=|baidu.+?wd=|baidu.+?kw=|baidu.+?word=|3721\.com.+?p=|Alltheweb.+?q=|soso.+?w=|115.+?q=|youdao.+?q=|sogou.+?query=|bing.+?q=|114.+?kw=)([^&]*)

以上正则是我根据网上的正则有所修改,让其支持soso、115、youdao、sogou、bing(必应)、114(或118114)这些搜索,感谢作者提供。因为网上转载太多,尚未注明原出处,因此我也无法标明原作者。

编码类型的识别

GB2312和UTF-8

从上面的例子我们可以看出,同样是搜索“秋寒博客”,但是不同的搜索对URL编码后,形成的字符串也不同。谷歌和必应下面是“%e7%a7%8b%e5%af%92%e5%8d%9a%e5%ae%a2”,而在百度却是“%C7%EF%BA%AE%B2%A9%BF%CD”。相信对网页编码了解的朋友都应该了解这是怎么回事,不同的页面编码(charset)对相同的字符进行编码后,产生的编码也是不同的。UTF-8默认产生的是UTF-8的编码,默认解码也是UTF-8。GB2312等也一样的。谷歌和必应用的是UTF-8编码,而百度用的是GB2312编码,就造成了相同的关键词在不同的搜索下产生了不同的字符串。

对于UTF-8和GB2312的解码都可以实现,但是如果不知道目标是什么编码方式,就不知道如何去解码了。如上面的两个字符串,初给你看,看不来是用何种编码方式。当然第一反应是通过搜索来判断编码方式,这种方法确实可行也有效。但是看看上面的正则,如果用这种方法,那么一个 if 后面要跟很多的 or 才行。网上一般用的也是这样的方法,我觉得这个不是最好的方法。我们得知的信息有:1、%xx%xx格式都是URL编码(UTF-8或GB2312);2、GB2312中汉字要两组%xx组成一个汉字,UTF-8要三组%xx组成一个汉字;3、如果用UTF-8解码方式去解GB2312的编码就会出现乱码。

单从长度和编码的范围我们根本无法辨别编码方式,只能通过其他方式来判断。根据上面3点,我们可以做一个假设:如果用UTF-8解码方式来解GB2312的编码会出现什么情况?因为UTF-8是有三组%xx组成的,而GB2312是由两组%XX组成的,如果用UTF-8的解码方式去解GB2312且能解码成功,那解码后的字符的长度一定会变短。例如:GB2312URL编码的“秋寒博客”(%C7%EF%BA%AE%B2%A9%BF%CD)用UTF-8解码,若能解码成功,解码后的字符长度会是2个半汉字。如果不能解码成功,不用说就是GB2312编码方式了。

OK,至此我们初步已经知道如何去识别URL的编码类型了,步骤如下:

1、获取关键字编码串;

2、取得编码串的组数(x),例如:“%C7%EF%BA%AE%B2%A9%BF%CD 为8组;

3、用UTF-8解码方式去解取得的编码串;

4、如果解码失败(即程序出错)跳到第 8 步;

5、如果解码成功,取得解码后的字符串长度(y),与全面的编码串的组数除以3比较;

6、如果 x!=y 那么跳转到第 8 步;

7、如果 x=y 那么得到的字符串即为关键字;

8、用GB2312方式解码,得到的字符串为关键字;

上面步骤中,有几点需要注意:

1、第1步中需要将非汉字的URL转义及英文去掉;

2、第2、3、5步中的编码串为上面提到的字符串;

3、第7、8步中解码需要对原字符串进行;

UNICODE

在测试的过程中,发现soguo从网页跳到图片去的时候,会将URL编码方式改为UNICODE。UNICODE的方式相对比较好区分,即判断是否为\uxxxx或%uxxxx的形式即可。这个相对简单,只分享在ASP中的解码函数。

以下代码来自CSDN论坛:

方法一:

response.Write vbsUnEscape("\u5c0f\u867e\u7c73")

Function vbsUnEscape(str)'解密

dim i,s,c

s=""

For i=1 to Len(str)

c=Mid(str,i,1)

If Mid(str,i,2)="\u" and i<=Len(str)-5 Then

If IsNumeric("&H" & Mid(str,i+2,4)) Then

s = s & CHRW(CInt("&H" & Mid(str,i+2,4)))

i = i+5

Else

s = s & c

End If

ElseIf c="%" and i<=Len(str)-2 Then

If IsNumeric("&H" & Mid(str,i+1,2)) Then

s = s & CHRW(CInt("&H" & Mid(str,i+1,2)))

i = i+2

Else

s = s & c

End If

Else

s = s & c

End If

Next

vbsUnEscape = s

End Function

方法二:

s = "\u5c0f\u867e\u7c73"

s = Replace(s, "\u", "%u")

Response.Write Unescape(s)

在C#中也没有发现能识别URL编码格式的函数或方法,不知在PHP和JAVA下有没有更好的方法呢?欢迎大家讨论。

来源:读者沈力投稿,原文地址

没有评论:

发表评论