最近对搜索引擎产生了浓厚的兴趣,于是便到网上查了一下关于搜索引擎相关的资料。网上关于Spider的资料很多,也很详细。这里呢我说一下自己在编写Spider的一些心得。
要开spider有很多语言可以选择,C/C++、java、php、.net、paython等等。我就选了最近比较熟悉的.net做为开发语言。
利用.net封装的 HttpWebRequest 和 HttpWebResponse 就可以很方便的发起HTTP请求并接受服务器段返回的数据。这里需要注意2点,一是在发送get请求时一定要注意 HttpWebRequest 的Referer和UserAgent属性。经过测试发现,如果不说明这2个属性的话,有些服务器是不会返回正确的数据的。二是HttpWebResponse方法,有很多人在这里遇到了接受到了的html数据时乱码的情况,经过我的摸索,要从2方面进行解决:1,检查返回的数据是否用了文档压缩技术。2,判断页面的编码集(utf-8,gb2312)。在判断页面编码的时候,我尝试了很多方法,比如判断ContentType属性,但这个属性要依赖于服务器的设置,并不是所有的网站都会返回编码信息;先把收到的流存入string,再通过判断流的信息来转换编码,但这样做总会在每行末出现乱码。于是使用的是最笨最原始的方法,先读取返回的数据,通过正则来获取meta信息,再用相应的编码再次发送http请求。
我这样做的效率是低了点,以后再来慢慢的优化吧。
代码如下:
public class GetContent
{
private string PageCode = Encoding.Default.ToString();
public long HtmlBytes;
public string Get_Http(string a_strUrl)
{
string strResult;
string encode = GetHtmlEncode(a_strUrl); // 获取页面编码
try
{
HttpWebRequest myReq = (HttpWebRequest)WebRequest.Create(a_strUrl);
myReq.KeepAlive = false;
myReq.Referer = "www.baidu.com";
//myReq.Timeout = 6000;
//myReq.ReadWriteTimeout = 6000;
myReq.UserAgent = "Mozilla/4.0+(compatible;+MSIE+7.0;+Windows+NT+5.1;+.NET+CLR+2.0.50727;+.NET+CLR+3.0.04506.30)";
HttpWebResponse HttpWResp = (HttpWebResponse)myReq.GetResponse();
//HtmlBytes = HttpWResp.ContentLength;
Stream myStream = HttpWResp.GetResponseStream();
//判断是否有GZIP加密
StreamReader sr;
if (HttpWResp.ContentEncoding.ToUpper() == "GZIP")
{
sr = new StreamReader(new GZipStream(myStream, CompressionMode.Decompress), Encoding.Default);
}
else
{
sr = new StreamReader(myStream, System.Text.Encoding.GetEncoding(encode));
}
//sr.Close();
strResult = sr.ReadToEnd();
HtmlBytes = strResult.Length;
HttpWResp.Close();
myStream.Close();
}
catch (Exception exp)
{
strResult = "错误:" + exp.Message;
}
return strResult;
}
private string GetHtmlEncode(string url)
{
string encode = "utf-8";
try
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.UserAgent = "Mozilla/4.0+(compatible;+MSIE+7.0;+Windows+NT+5.1;+.NET+CLR+2.0.50727;+.NET+CLR+3.0.04506.30)";
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Stream resStream = response.GetResponseStream();
StreamReader sr;
System.Text.Encoding enc = Encoding.ASCII;
if (response.ContentEncoding.ToUpper() == "GZIP")
{
sr = new StreamReader(new GZipStream(resStream, CompressionMode.Decompress), enc);
}
else
{
sr = new StreamReader(resStream, enc, true);
}
//StreamReader strResponse = new StreamReader(resStream, enc, true);
string str = sr.ReadToEnd();
response.Close();
resStream.Close();
Regex regEncoding = new Regex(@"charset=([/w-]*)/.*"); //通过meta信息来获取编码
Match m = regEncoding.Match(str);
if (m.Success)
{
encode = m.Groups[1].ToString();
encode = encode.ToLower();
}
}
catch { }
return encode;
}
}
这里我只实现了最基本的页面抓取功能,当然市面上的搜索引擎可没有这么简单。以后再一步一步的来完善我的搜索程序。