利用C#实现网络爬虫

2019-12-30 11:54:11王旭

 4. 提取页面链接

提取链接用正则表达式就能搞定了,不懂的可以上网搜。

下面的字符串就能匹配到页面中的链接

http://www.easck.com/?%&=]*)?

详细见代码


private string[] GetLinks(string html)
{
 const string pattern = @"http://www.easck.com/?%&=]*)?";
 Regex r = new Regex(pattern, RegexOptions.IgnoreCase); //新建正则模式
 MatchCollection m = r.Matches(html); //获得匹配结果
 string[] links = new string[m.Count]; 

 for (int i = 0; i < m.Count; i++)
 {
  links[i] = m[i].ToString(); //提取出结果
 }
 return links;
}

5. 链接的过滤

不是所有的链接我们都需要下载,所以通过过滤,去掉我们不需要的链接

这些链接一般有:

1)、已经下载的链接
2)、深度过大的链接
3)、其他的不需要的资源,如图片、CSS等


//判断链接是否已经下载或者已经处于未下载集合中
private bool UrlExists(string url) 
{
 bool result = _urlsUnload.ContainsKey(url);
 result |= _urlsLoaded.ContainsKey(url);
 return result;
}

private bool UrlAvailable(string url)
{
 if (UrlExists(url))
 {
  return false; //已经存在
 }
 if (url.Contains(".jpg") || url.Contains(".gif")
  || url.Contains(".png") || url.Contains(".css")
  || url.Contains(".js"))
 {
  return false; //去掉一些图片之类的资源
 }
 return true;
}

private void AddUrls(string[] urls, int depth)
{
 if (depth >= _maxDepth)
 {
  return; //深度过大
 }
 foreach (string url in urls)
 {
  string cleanUrl = url.Trim(); //去掉前后空格
  cleanUrl = cleanUrl.TrimEnd('/'); //统一去掉最后面的'/'
  if (UrlAvailable(cleanUrl))
  {
   if (cleanUrl.Contains(_baseUrl))
   {
    _urlsUnload.Add(cleanUrl, depth); //是内链,直接加入未下载集合
   }
   else
   {
    // 外链处理
   }
  }
 }
}

 第34行的_baseUrl是爬取的基地址,如http://www.easck.com/,将会保存为news.sina.com.cn,当一个URL包含此字符串时,说明是该基地址下的链接;否则为外链。 

_baseUrl的处理如下,_rootUrl是第一个要下载的URL


/// <summary>
/// 下载根Url
/// </summary>
public string RootUrl
{
 get
 {
  return _rootUrl;
 }
 set
 {
  if (!value.Contains("http://www.easck.com//全站的话去掉www
  _baseUrl = _baseUrl.Replace("http://www.easck.com/p>