HTTP请求工具类(功能:1、获取网页html;2、下载网络图片;):

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Drawing;
  4. using System.IO;
  5. using System.Linq;
  6. using System.Net;
  7. using System.Text;
  8. using System.Threading.Tasks;
  9. using System.Windows.Forms;
  10.  
  11. namespace Utils
  12. {
  13. /// <summary>
  14. /// HTTP请求工具类
  15. /// </summary>
  16. public class HttpRequestUtil
  17. {
  18. /// <summary>
  19. /// 获取页面html
  20. /// </summary>
  21. public static string GetPageHtml(string url)
  22. {
  23. // 设置参数
  24. HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
  25. request.UserAgent = "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0)";
  26. //发送请求并获取相应回应数据
  27. HttpWebResponse response = request.GetResponse() as HttpWebResponse;
  28. //直到request.GetResponse()程序才开始向目标网页发送Post请求
  29. Stream responseStream = response.GetResponseStream();
  30. StreamReader sr = new StreamReader(responseStream, Encoding.UTF8);
  31. //返回结果网页(html)代码
  32. string content = sr.ReadToEnd();
  33. return content;
  34. }
  35.  
  36. /// <summary>
  37. /// Http下载文件
  38. /// </summary>
  39. public static void HttpDownloadFile(string url, int minWidth, int minHeight)
  40. {
  41. int pos = url.LastIndexOf("/") + ;
  42. string fileName = url.Substring(pos);
  43. string path = Application.StartupPath + "\\download";
  44. if (!Directory.Exists(path))
  45. {
  46. Directory.CreateDirectory(path);
  47. }
  48. string filePathName = path + "\\" + fileName;
  49. if (File.Exists(filePathName)) return;
  50.  
  51. // 设置参数
  52. HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
  53. request.UserAgent = "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0)";
  54. request.Proxy = null;
  55. //发送请求并获取相应回应数据
  56. HttpWebResponse response = request.GetResponse() as HttpWebResponse;
  57. //直到request.GetResponse()程序才开始向目标网页发送Post请求
  58. Stream responseStream = response.GetResponseStream();
  59.  
  60. MemoryStream memoryStream = new MemoryStream();
  61. byte[] bArr = new byte[];
  62. int size = responseStream.Read(bArr, , (int)bArr.Length);
  63. while (size > )
  64. {
  65. memoryStream.Write(bArr, , size);
  66. size = responseStream.Read(bArr, , (int)bArr.Length);
  67. }
  68. Image tempImage = System.Drawing.Image.FromStream(memoryStream, true);
  69. int imageHeight = tempImage.Height;
  70. int imageWidth = tempImage.Width;
  71. if (imageHeight >= minHeight && imageWidth >= minWidth)
  72. {
  73. memoryStream.Seek(, SeekOrigin.Begin);
  74. size = memoryStream.Read(bArr, , (int)bArr.Length);
  75. FileStream fs = new FileStream(filePathName, FileMode.Create);
  76. while (size > )
  77. {
  78. fs.Write(bArr, , size);
  79. size = memoryStream.Read(bArr, , (int)bArr.Length);
  80. }
  81. fs.Close();
  82. }
  83. memoryStream.Close();
  84. responseStream.Close();
  85. }
  86. }
  87. }

VisitedHelper类:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Linq;
  5. using System.Text;
  6. using System.Threading.Tasks;
  7. using System.Windows.Forms;
  8.  
  9. namespace Utils
  10. {
  11. /// <summary>
  12. /// 已访问的网址列表
  13. /// </summary>
  14. public class VisitedHelper
  15. {
  16. private static List<string> m_VisitedList = new List<string>();
  17.  
  18. #region 判断是否已访问
  19. /// <summary>
  20. /// 判断是否已访问
  21. /// </summary>
  22. public static bool IsVisited(string url)
  23. {
  24. if (m_VisitedList.Exists(a => a == url))
  25. {
  26. return true;
  27. }
  28. return false;
  29. }
  30. #endregion
  31.  
  32. #region 添加已访问
  33. /// <summary>
  34. /// 添加已访问
  35. /// </summary>
  36. public static void Add(string url)
  37. {
  38. m_VisitedList.Add(url);
  39. }
  40. #endregion
  41.  
  42. }
  43. }

多线程爬取网页代码:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Data;
  5. using System.Drawing;
  6. using System.IO;
  7. using System.Linq;
  8. using System.Text;
  9. using System.Text.RegularExpressions;
  10. using System.Threading;
  11. using System.Threading.Tasks;
  12. using System.Windows.Forms;
  13. using Utils;
  14.  
  15. namespace 爬虫
  16. {
  17. public partial class Form1 : Form
  18. {
  19. private static int m_MinWidth = ;
  20. private static int m_MinHeight = ;
  21. private static int m_CompletedCount = ;
  22.  
  23. public Form1()
  24. {
  25. InitializeComponent();
  26. }
  27.  
  28. private void button1_Click(object sender, EventArgs e)
  29. {
  30. ThreadPool.SetMaxThreads(, );
  31. int.TryParse(txtMinWidth.Text, out m_MinWidth);
  32. int.TryParse(txtMinHeight.Text, out m_MinHeight);
  33. button1.Enabled = false;
  34. lblMsg.Text = "正在爬取图片…";
  35. timer1.Start();
  36. new Thread(new ThreadStart(delegate()
  37. {
  38. Crawling(txtUrl.Text, null);
  39. })).Start();
  40. }
  41.  
  42. /// <summary>
  43. /// 爬取
  44. /// </summary>
  45. private void Crawling(string url, string host)
  46. {
  47. if (!VisitedHelper.IsVisited(url))
  48. {
  49. VisitedHelper.Add(url);
  50.  
  51. if (host == null)
  52. {
  53. host = GetHost(url);
  54. }
  55.  
  56. string pageHtml = HttpRequestUtil.GetPageHtml(url);
  57. Regex regA = new Regex(@"<a[\s]+[^<>]*href=(?:""|')([^<>""']+)(?:""|')[^<>]*>[^<>]+</a>", RegexOptions.IgnoreCase);
  58. Regex regImg = new Regex(@"<img[\s]+[^<>]*src=(?:""|')([^<>""']+(?:jpg|jpeg|png|gif))(?:""|')[^<>]*>", RegexOptions.IgnoreCase);
  59.  
  60. MatchCollection mcImg = regImg.Matches(pageHtml);
  61. foreach (Match mImg in mcImg)
  62. {
  63. string imageUrl = mImg.Groups[].Value;
  64. try
  65. {
  66. int imageWidth = GetImageWidthOrHeight(mImg.Value, true);
  67. int imageHeight = GetImageWidthOrHeight(imageUrl, false);
  68. if (imageWidth >= m_MinWidth && imageHeight >= m_MinHeight)
  69. {
  70. if (imageUrl.IndexOf("javascript") == -)
  71. {
  72. if (imageUrl.IndexOf("http") == )
  73. {
  74. HttpRequestUtil.HttpDownloadFile(imageUrl, m_MinWidth, m_MinHeight);
  75. }
  76. else
  77. {
  78. HttpRequestUtil.HttpDownloadFile(host + imageUrl, m_MinWidth, m_MinHeight);
  79. }
  80. }
  81. }
  82. }
  83. catch { }
  84. }
  85.  
  86. //递归遍历
  87. MatchCollection mcA = regA.Matches(pageHtml);
  88. foreach (Match mA in mcA)
  89. {
  90. try
  91. {
  92. string nextUrl = mA.Groups[].Value;
  93. if (nextUrl.IndexOf("javascript") == -)
  94. {
  95. if (nextUrl.IndexOf("http") == )
  96. {
  97. if (GetHost(url) == host)
  98. {
  99. ThreadPool.QueueUserWorkItem(new WaitCallback(delegate(object obj)
  100. {
  101. try
  102. {
  103. Crawling(nextUrl, host);
  104. m_CompletedCount++;
  105. }
  106. catch { }
  107. }));
  108. }
  109. }
  110. else
  111. {
  112. if (GetHost(url) == host)
  113. {
  114. ThreadPool.QueueUserWorkItem(new WaitCallback(delegate(object obj)
  115. {
  116. try
  117. {
  118. Crawling(host + nextUrl, host);
  119. m_CompletedCount++;
  120. }
  121. catch { }
  122. }));
  123. }
  124. }
  125. }
  126. }
  127. catch { }
  128. }
  129. }
  130. } //end Crawling方法
  131.  
  132. /// <summary>
  133. /// 获取主机
  134. /// </summary>
  135. private string GetHost(string url)
  136. {
  137. Regex regHost = new Regex(@"(?:http|https)://[a-z0-9\-\.:]+", RegexOptions.IgnoreCase);
  138. Match mHost = regHost.Match(url);
  139. return mHost.Value + "/";
  140. }
  141.  
  142. //计时器事件
  143. private void timer1_Tick(object sender, EventArgs e)
  144. {
  145. int workerThreads;
  146. int completionPortThreads;
  147. ThreadPool.GetAvailableThreads(out workerThreads, out completionPortThreads);
  148. if (workerThreads == && m_CompletedCount > )
  149. {
  150. lblMsg.Text = "已结束";
  151. }
  152. else
  153. {
  154. lblMsg.Text = "正在爬取图片…";
  155. }
  156. }
  157.  
  158. /// <summary>
  159. /// 获取图片宽度或高度
  160. /// </summary>
  161. private int GetImageWidthOrHeight(string imageTagString, bool isWidth)
  162. {
  163. string tag = isWidth ? "width" : "height";
  164. Regex reg = new Regex(string.Format(@"{0}=""([\d\.]+)""", tag), RegexOptions.IgnoreCase);
  165. Match match = reg.Match(imageTagString);
  166. if (match.Success)
  167. {
  168. return (int)Convert.ToDouble(match.Groups[].Value);
  169. }
  170. else
  171. {
  172. reg = new Regex(string.Format(@"{0}[\s]*:[\s]*([\d\.]+)[\s]*px[\s]*;", tag), RegexOptions.IgnoreCase);
  173. match = reg.Match(imageTagString);
  174. if (match.Success)
  175. {
  176. return (int)Convert.ToDouble(match.Groups[].Value);
  177. }
  178. }
  179. return int.MaxValue;
  180. }
  181.  
  182. } //end Form1类
  183.  
  184. /// <summary>
  185. /// 跨线程访问控件的委托
  186. /// </summary>
  187. public delegate void InvokeDelegate();
  188. }

截图:

C#实现网页爬虫的更多相关文章

  1. cURL 学习笔记与总结(2)网页爬虫、天气预报

    例1.一个简单的 curl 获取百度 html 的爬虫程序(crawler): spider.php <?php /* 获取百度html的简单网页爬虫 */ $curl = curl_init( ...

  2. c#网页爬虫初探

    一个简单的网页爬虫例子! html代码: <head runat="server"> <title>c#爬网</title> </head ...

  3. 网页爬虫--scrapy入门

    本篇从实际出发,展示如何用网页爬虫.并介绍一个流行的爬虫框架~ 1. 网页爬虫的过程 所谓网页爬虫,就是模拟浏览器的行为访问网站,从而获得网页信息的程序.正因为是程序,所以获得网页的速度可以轻易超过单 ...

  4. 网页爬虫的设计与实现(Java版)

    网页爬虫的设计与实现(Java版)     最近为了练手而且对网页爬虫也挺感兴趣,决定自己写一个网页爬虫程序. 首先看看爬虫都应该有哪些功能. 内容来自(http://www.ibm.com/deve ...

  5. Python 网页爬虫 & 文本处理 & 科学计算 & 机器学习 & 数据挖掘兵器谱(转)

    原文:http://www.52nlp.cn/python-网页爬虫-文本处理-科学计算-机器学习-数据挖掘 曾经因为NLTK的缘故开始学习Python,之后渐渐成为我工作中的第一辅助脚本语言,虽然开 ...

  6. [resource-]Python 网页爬虫 & 文本处理 & 科学计算 & 机器学习 & 数据挖掘兵器谱

    reference: http://www.52nlp.cn/python-%e7%bd%91%e9%a1%b5%e7%88%ac%e8%99%ab-%e6%96%87%e6%9c%ac%e5%a4% ...

  7. 网页抓取:PHP实现网页爬虫方式小结

    来源:http://www.ido321.com/1158.html 抓取某一个网页中的内容,需要对DOM树进行解析,找到指定节点后,再抓取我们需要的内容,过程有点繁琐.LZ总结了几种常用的.易于实现 ...

  8. Java正则表达式--网页爬虫

    网页爬虫:其实就一个程序用于在互联网中获取符合指定规则的数据 爬取邮箱地址,爬取的源不同,本地爬取或者是网络爬取 (1)爬取本地数据: public static List<String> ...

  9. 从robots.txt開始网页爬虫之旅

    做个网页爬虫或搜索引擎(下面统称蜘蛛程序)的各位一定不会陌生,在爬虫或搜索引擎訪问站点的时候查看的第一个文件就是robots.txt了.robots.txt文件告诉蜘蛛程序在server上什么文件是能 ...

  10. Python网页爬虫(一)

    很多时候我们想要获得网站的数据,但是网站并没有提供相应的API调用,这时候应该怎么办呢?还有的时候我们需要模拟人的一些行为,例如点击网页上的按钮等,又有什么好的解决方法吗?这些正是python和网页爬 ...

随机推荐

  1. 每周一书-2016年8月15日到21日(bootstrap基础教程)获奖读者公布

    本次赠书 由微信昵称为“………….”的网友以10个赞获得. 请这位网友,订阅号回复你的联系方式,明天给你邮递这本书.谢谢!同时感谢<把时间当朋友>的获奖者“永梅”为<bootsrap ...

  2. [.net 面向对象程序设计进阶] (6) Lamda表达式(二) 表达式树快速入门

    [.net 面向对象程序设计进阶] (6) Lamda表达式(二) 表达式树快速入门 本节导读: 认识表达式树(Expression Tree),学习使用Lambda创建表达式树,解析表达式树. 学习 ...

  3. 【面试必备】javascript的原型和继承

    原型.闭包.作用域等知识可以说是js中面试必考的东西,通过你理解的深度也就能衡量出你基本功是否扎实.今天来复习一下javascript的原型和继承,虽说是老生常谈的话题,但对于这些知识,自己亲手写一遍 ...

  4. Unity3D热更新全书-脚本(五) NGUI

    让我们实际的研究一下如何将NGUI和C#LightEvil结合起来. 这里使用NGUI2.7,因为他是一个开源的版本,NGUI最新的版本未经作者的许可,是不可以带入我们的开源项目使用的. 这个例子完成 ...

  5. Android 神兵利器—— Adb 常用命令

    总结的Android工具类文章: Android 神兵利器-- Adb 常用命令 Android 神兵利器-- Git 常用命令 Adb的全称为Android Debug Bridge,是管理andr ...

  6. 解析Visual Studio 2015促进生产力的10个新功能

    1 性能提示 Performance Tips 当我们想知道执行一段代码所耗费的时间时,需要借助于.NET 框架的Stopwatch类,像下面这样: class Program { static vo ...

  7. Topology and Geometry in OpenCascade-Face

    Topology and Geometry in OpenCascade-Face eryar@163.com 摘要Abstract:本文简要介绍了几何造型中的边界表示法(BRep),并结合程序说明O ...

  8. PHP 自制日历

    最近的一个项目中,需要将数据用日历方式显示,网上有很多的JS插件,后面为了自己能有更大的控制权,决定自己制作一个日历显示.如下图所示: 一.计算数据 1.new一个Calendar类 2.初始化两个下 ...

  9. Nodejs学习笔记(四)——支持Mongodb

    前言:回顾前面零零碎碎写的三篇挂着Nodejs学习笔记的文章,着实有点名不副实,当然,这篇可能还是要继续走着离主线越走越远的路子,从简短的介绍什么是Nodejs,到如何寻找一个可以调试的Nodejs ...

  10. 开发人员看测试之运行Github中的JBehave项目

    本文要阐述的主要有两点,一是介绍自动化测试框架JBehave,二是介绍如何在Github上拉项目,编译成myeclipse环境中的项目,并最终导入Myeclipse中运行. JBehave是何物? J ...