随笔 - 1330  文章 - 1  评论 - 376  0

   View二期开发正式启动,一开始就碰到了麻烦事,因为在统计模块中,需要得到来源搜索链接的关键字,所以一开始就用正则把关键字部分匹配出来,然后用自带的 Uri.UnescapeDataString() 将Urlcoding转换为文字。

  本来一切都很顺利,结果将百度,网易搜索加到规则里面,就开始报错了。我猜想可能是和编码有关系,因为Google一向都是UTF-8,国内的网站大多偏向使用GB2312,所以出现这个问题我还不是很担心。

  哪里知道,这个问题的严重性,让我差点对程序算法的研究失去信心。因为今天听到有个人说我胆子好大,居然敢把所有链接的事件给改掉了,万一还有相同事件,那么就会出严重的问题。我一向认为我还是个比较心细的人,在我做那件大胆的事情前,我是仔细地咨询过有没有相同事件存在,在得到肯定的答复后,我才开始做的。代码虽然不多,但是我敢说里面能考虑到的,不能考虑到的错误,我基本已经都做到。

  回到正题,在网上一搜索,发现asp.net这方面的资料真的是太少了,然后看了看ASP和PHP的,发现做法十分复杂,而且还容易出错,甚至还要建一个gb2312到utf-8的编码对照表。

  我坚信微软一定会给出一个完美的解决方案,于是开始查MSDN,从Encoding入手,发现存在转换编码的方法。但是问题又出现了,因为我得到的是URL形式的字符串,现在还不知道这个字符串是属于utf-8的,还是gb2312的,所以不能使用UnescapeDataString转换成文字后再进行转码,因为这样马上会报错。

  于是开始分析gb2312和utf-8的编码原理,发现他们在.net里是存在关联性的,一个是2位编码,一个是三位编码,于是我试者将gb2312的编码进行分解,将每2位作为2个16进制的byte类型放入一个byte数组里面,然后通过正常的转码方式转为utf-8的byte类型,然后放入char里面,最后转成正常文字。

 

结果马上就揭晓了,居然成功了,然后再接再厉,写了一个搜索引擎类型判断的方法,于是一切就这么给解决。

  下面给出代码,希望可以帮到有用的朋友:

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Text.RegularExpressions;
using System.Text;
/// <summary>
/// 搜索引擎处理
/// </summary>
public class ExJudgeSystem
{
  
public ExJudgeSystem()
  {
  }
  
#region 初始化变量
  
//搜索引擎特征
  private string[][] _Enginers = new string[][] {
    
new string[]{"google","utf8","q"},
    
new string[]{"baidu","gb2312","wd"},
    
new string[]{"yahoo","utf8","p"},
    
new string[]{"yisou","utf8","search"},
    
new string[]{"live","utf8","q"},
    
new string[]{"tom","gb2312","word"},
    
new string[]{"163","gb2312","q"},
    
new string[]{"iask","gb2312","k"},
    
new string[]{"soso","gb2312","w"},
    
new string[]{"sogou","gb2312","query"},
    
new string[]{"zhongsou","gb2312","w"},
    
new string[]{"3721","gb2312","p"},
    
new string[]{"openfind","utf8","q"},
    
new string[]{"alltheweb","utf8","q"},
    
new string[]{"lycos","utf8","query"},
    
new string[]{"onseek","utf8","q"}
  };
  
//搜索引擎名称
  private string _EngineName = "";
  
public string EngineName
  {
    
get
    {
      
return _EngineName;
    }
  }
  
//搜索引擎编码
  private string _Coding = "utf8";
  
public string Coding
  {
    
get
    {
      
return _Coding;
    }
  }
  
//搜索引擎关键字查询参数名称
  private string _RegexWord = "";
  
public string RegexWord
  {
    
get
    {
      
return _RegexWord;
    }
  }
  
private string _Regex = @"(";
#endregion
  
#region 搜索引擎关键字
  
//建立搜索关键字正则表达式
  public void EngineRegEx(string myString)
  {
    
for (int i = 0, j = _Enginers.Length; i < j; i++)
    {
      
if (myString.Contains(_Enginers[i][0]))
      {
        _EngineName 
= _Enginers[i][0];
        _Coding 
= _Enginers[i][1];
        _RegexWord 
= _Enginers[i][2];
        _Regex 
+= _EngineName + @".+.*[?/&]" + _RegexWord + @"[=:])(?<key>[^&]*)";
        
break;
      }
    }
  }
  
//得到搜索引擎关键字
  public string SearchKey(string myString)
  {
    EngineRegEx(myString.ToLower());
    
if (_EngineName != "")
    {
      Regex myReg 
= new Regex(_Regex, RegexOptions.IgnoreCase);
      Match matche 
= myReg.Match(myString);
      myString 
= matche.Groups["key"].Value;
      
//去处表示为空格的+
      myString = myString.Replace("+"" ");
      
if (_Coding == "gb2312")
      {
        myString 
= GetUTF8String(myString);
      }
      
else
      {
        myString 
= Uri.UnescapeDataString(myString);
      }
    }
    
return myString;
  }
  
//整句转码
  public string GetUTF8String(string myString)
  {
    Regex myReg 
= new Regex("(?<key>%..%..)", RegexOptions.IgnoreCase);
    MatchCollection matches 
= myReg.Matches(myString);
    
string myWord;
    
for (int i = 0, j = matches.Count; i < j; i++)
    {
      myWord 
= matches[i].Groups["key"].Value.ToString();
      myString 
= myString.Replace(myWord, GB2312ToUTF8(myWord));
    }
    
return myString;
  }
  
//单字GB2312转UTF8 URL编码
  public string GB2312ToUTF8(string myString)
  {
    
string[] myWord = myString.Split('%');
    
byte[] myByte = new byte[] { Convert.ToByte(myWord[1], 16), Convert.ToByte(myWord[2], 16) };
    Encoding GB 
= Encoding.GetEncoding("GB2312");
    Encoding U8 
= Encoding.UTF8;
    myByte 
= Encoding.Convert(GB, U8, myByte);
    
char[] Chars = new char[U8.GetCharCount(myByte, 0, myByte.Length)];
    U8.GetChars(myByte, 
0, myByte.Length, Chars, 0);
    
return new string(Chars);
  }
  
#endregion
  
//判断否为搜索引擎爬虫,并返回其类型
  public string isCrawler(string SystemInfo)
  {
    
string[] BotList = new string[] { "Google""Baidu""MSN""Yahoo""TMCrawler""iask""Sogou" };
    
foreach (string Bot in BotList)
    {
      
if (SystemInfo.ToLower().Contains(Bot.ToLower()))
      {
        
return Bot;
      }
    }
    
return "null";
  }
}

     下午下班的时候,在出地铁的时候捡到一个钱包,打开看了一下有几百块,嘿嘿!心痒痒的,不过小学老师就教导我们拾金不昧,我在站口傻站了半天,等掉钱包的人回来领,没有结果,只好把钱包交给地铁的工作人员。社会的素质文明是需要从每个人开始做起,而不是每天说些华而不实的废话。

转自:http://tech.ddvip.com/2008-10/122308885173395.html

posted on 2009-07-20 11:54 钱途无梁 阅读(...) 评论(...) 编辑 收藏