在编写一般的爬虫程序或者搜索引擎时,首先就是对队列中的url进行处理,当我们得到一条URL信息的时候,我们希望能够将其处理成合适的部分。
http://www2.scut.edu.cn/scutnxq/s/27/t/3/0f/6b/info3947.htm?p=12&sd=12
对于上面这条URL,我们可以将其分为五个部分:
public static string _HOST = "host"; //主机:www2.scut.edu.cn
public static string _RESOURCE = "resource"; //资源:scutnxq/s/27/t/3/0f/6b/info3947.htm
public static string _PROTOCOL = "protocol"; //协议:http
public static string _URL = "url"; //无
public static string _PARAM = "param"; //参数:p=12&sd=12
对于正则表达式的使用,不是本文的重点,因此直接给出解析的正则表达式:
(?<url>(?<protocol>^[a-z][a-z0-9+\-.]*)://(?<host>[a-z0-9\-._~%]+|\[[a-f0-9:.]+\]|\[v[a-f0-9][a-z0-9\-._~%!$&'()*+,;=:]+\]))(?<resource>[a-z0-9\-._~%!$&'()*+,;=:@/]*/?)(?<param>(\?[a-z0-9\-._~%!$&'()*+,;=:@/?]*)?)$
在.NET中,可以对正则表达式匹配的部分进行分组,因此在表达式中加入诸如?<key>的部分,便于通过match对象获取各部分的值。
public static string[] KEYS = { _HOST, _RESOURCE, _PROTOCOL, _URL, _PARAM };
private Dictionary
url = new Dictionary
();
将上述的字段添加到数组中,便于遍历,接着通过以下简单的程序将各部分解析出来。
private void match(string src,string pattern)
{
MatchCollection mc = Regex.Matches(src, pattern);
foreach (Match m in mc)
{
if (m.Success)
{
for (int i = 0; i < KEYS.Length; i++)
{
add(KEYS[i], m);
}
}
}
}
其中add方法的实现是:
public void add(string key, Match m)
{
if (!"".Equals(m.Groups[key].Value))
url.Add(key, m.Groups[key].Value);
}
public string get(string key)
{
if (!url.ContainsKey(key))
return "";
return url[key];
}
在该对象的外部,通过get方法和定义静态字段的名称,获取相应的值。
string[] urls = { "http://www2.scut.edu.cn/scutnxq/s/27/t/3/0f/6b/info3947.htm?p=12&sd=12",
"http://www2.scut.edu.cn/scutnxq/s/27/t/3/0f/6b/info3947.htm",
"http://www.scut.edu.cn",
"scutnxq/s/27/t/3/0f/6b/info3947.htm"
};
将各种URL进行测试,保证正则表达式的正确。
有很多正则表达式的在线测试工具,推荐一个较为好用的:http://www.myregexp.com/,需要安装java环境。