[转]正则表达式相关:C# 抓取网页类(获取网页中所有信息)

时间:2021-05-29 21:42:13
  1. using System;
  2. using System.Data;
  3. using System.Configuration;
  4. using System.Net;
  5. using System.IO;
  6. using System.Text;
  7. using System.Collections.Generic;
  8. using System.Text.RegularExpressions;
  9. using System.Threading;
  10. using System.Web;
  11. using System.Web.UI.MobileControls;
  12. /// <summary>
  13. /// 网页类
  14. /// </summary>
  15. public class WebPage
  16. {
  17. #region 私有成员
  18. private Uri m_uri;   //url
  19. private List<Link> m_links;    //此网页上的链接
  20. private string m_title;        //标题
  21. private string m_html;         //HTML代码
  22. private string m_outstr;       //网页可输出的纯文本
  23. private bool m_good;           //网页是否可用
  24. private int m_pagesize;       //网页的大小
  25. private static Dictionary<string, CookieContainer> webcookies = new Dictionary<string, CookieContainer>();//存放所有网页的Cookie
  26. #endregion
  27. #region 属性
  28. /// <summary>
  29. /// 通过此属性可获得本网页的网址,只读
  30. /// </summary>
  31. public string URL
  32. {
  33. get
  34. {
  35. return m_uri.AbsoluteUri;
  36. }
  37. }
  38. /// <summary>
  39. /// 通过此属性可获得本网页的标题,只读
  40. /// </summary>
  41. public string Title
  42. {
  43. get
  44. {
  45. if (m_title == "")
  46. {
  47. Regex reg = new Regex(@"(?m)<title[^>]*>(?<title>(?:\w|\W)*?)</title[^>]*>", RegexOptions.Multiline | RegexOptions.IgnoreCase);
  48. Match mc = reg.Match(m_html);
  49. if (mc.Success)
  50. m_title = mc.Groups["title"].Value.Trim();
  51. }
  52. return m_title;
  53. }
  54. }
  55. public string M_html
  56. {
  57. get
  58. {
  59. if (m_html == null)
  60. {
  61. m_html = "";
  62. }
  63. return m_html;
  64. }
  65. }
  66. /// <summary>
  67. /// 此属性获得本网页的所有链接信息,只读
  68. /// </summary>
  69. public List<Link> Links
  70. {
  71. get
  72. {
  73. if (m_links.Count == 0) getLinks();
  74. return m_links;
  75. }
  76. }
  77. /// <summary>
  78. /// 此属性返回本网页的全部纯文本信息,只读
  79. /// </summary>
  80. public string Context
  81. {
  82. get
  83. {
  84. if (m_outstr == "") getContext(Int16.MaxValue);
  85. return m_outstr;
  86. }
  87. }
  88. /// <summary>
  89. /// 此属性获得本网页的大小
  90. /// </summary>
  91. public int PageSize
  92. {
  93. get
  94. {
  95. return m_pagesize;
  96. }
  97. }
  98. /// <summary>
  99. /// 此属性获得本网页的所有站内链接
  100. /// </summary>
  101. public List<Link> InsiteLinks
  102. {
  103. get
  104. {
  105. return getSpecialLinksByUrl("^http://" + m_uri.Host, Int16.MaxValue);
  106. }
  107. }
  108. /// <summary>
  109. /// 此属性表示本网页是否可用
  110. /// </summary>
  111. public bool IsGood
  112. {
  113. get
  114. {
  115. return m_good;
  116. }
  117. }
  118. /// <summary>
  119. /// 此属性表示网页的所在的网站
  120. /// </summary>
  121. public string Host
  122. {
  123. get
  124. {
  125. return m_uri.Host;
  126. }
  127. }
  128. #endregion
  129. /// <summary>
  130. /// 从HTML代码中分析出链接信息
  131. /// </summary>
  132. /// <returns>List<Link></returns>
  133. private List<Link> getLinks()
  134. {
  135. if (m_links.Count == 0)
  136. {
  137. Regex[] regex = new Regex[2];
  138. regex[0] = new Regex(@"<a\shref\s*=""(?<URL>[^""]*).*?>(?<title>[^<]*)</a>", RegexOptions.IgnoreCase | RegexOptions.Singleline);
  139. regex[1] = new Regex("<[i]*frame[^><]+src=(\"|')?(?<url>([^>\"'\\s)])+)(\"|')?[^>]*>", RegexOptions.IgnoreCase);
  140. for (int i = 0; i < 2; i++)
  141. {
  142. Match match = regex[i].Match(m_html);
  143. while (match.Success)
  144. {
  145. try
  146. {
  147. string url = HttpUtility.UrlDecode(new Uri(m_uri, match.Groups["URL"].Value).AbsoluteUri);
  148. string text = "";
  149. if (i == 0) text = new Regex("(<[^>]+>)|(\\s)|( )|&|\"", RegexOptions.Multiline | RegexOptions.IgnoreCase).Replace(match.Groups["text"].Value, "");
  150. Link link = new Link();
  151. link.Text = text;
  152. link.NavigateUrl = url;
  153. m_links.Add(link);
  154. }
  155. catch (Exception ex) { Console.WriteLine(ex.Message); };
  156. match = match.NextMatch();
  157. }
  158. }
  159. }
  160. return m_links;
  161. }
  162. /// <summary>
  163. /// 此私有方法从一段HTML文本中提取出一定字数的纯文本
  164. /// </summary>
  165. /// <param name="instr">HTML代码</param>
  166. /// <param name="firstN">提取从头数多少个字</param>
  167. /// <param name="withLink">是否要链接里面的字</param>
  168. /// <returns>纯文本</returns>
  169. private string getFirstNchar(string instr, int firstN, bool withLink)
  170. {
  171. if (m_outstr == "")
  172. {
  173. m_outstr = instr.Clone() as string;
  174. m_outstr = new Regex(@"(?m)<script[^>]*>(\w|\W)*?</script[^>]*>", RegexOptions.Multiline | RegexOptions.IgnoreCase).Replace(m_outstr, "");
  175. m_outstr = new Regex(@"(?m)<style[^>]*>(\w|\W)*?</style[^>]*>", RegexOptions.Multiline | RegexOptions.IgnoreCase).Replace(m_outstr, "");
  176. m_outstr = new Regex(@"(?m)<select[^>]*>(\w|\W)*?</select[^>]*>", RegexOptions.Multiline | RegexOptions.IgnoreCase).Replace(m_outstr, "");
  177. if (!withLink) m_outstr = new Regex(@"(?m)<a[^>]*>(\w|\W)*?</a[^>]*>", RegexOptions.Multiline | RegexOptions.IgnoreCase).Replace(m_outstr, "");
  178. Regex objReg = new System.Text.RegularExpressions.Regex("(<[^>]+?>)| ", RegexOptions.Multiline | RegexOptions.IgnoreCase);
  179. m_outstr = objReg.Replace(m_outstr, "");
  180. Regex objReg2 = new System.Text.RegularExpressions.Regex("(\\s)+", RegexOptions.Multiline | RegexOptions.IgnoreCase);
  181. m_outstr = objReg2.Replace(m_outstr, " ");
  182. }
  183. return m_outstr.Length > firstN ? m_outstr.Substring(0, firstN) : m_outstr;
  184. }
  185. #region 公有文法
  186. /// <summary>
  187. /// 此公有方法提取网页中一定字数的纯文本,包括链接文字
  188. /// </summary>
  189. /// <param name="firstN">字数</param>
  190. /// <returns></returns>
  191. public string getContext(int firstN)
  192. {
  193. return getFirstNchar(m_html, firstN, true);
  194. }
  195. /// <summary>
  196. /// 此公有方法从本网页的链接中提取一定数量的链接,该链接的URL满足某正则式
  197. /// </summary>
  198. /// <param name="pattern">正则式</param>
  199. /// <param name="count">返回的链接的个数</param>
  200. /// <returns>List<Link></returns>
  201. public List<Link> getSpecialLinksByUrl(string pattern, int count)
  202. {
  203. if (m_links.Count == 0) getLinks();
  204. List<Link> SpecialLinks = new List<Link>();
  205. List<Link>.Enumerator i;
  206. i = m_links.GetEnumerator();
  207. int cnt = 0;
  208. while (i.MoveNext() && cnt < count)
  209. {
  210. if (new Regex(pattern, RegexOptions.Multiline | RegexOptions.IgnoreCase).Match(i.Current.NavigateUrl).Success)
  211. {
  212. SpecialLinks.Add(i.Current);
  213. cnt++;
  214. }
  215. }
  216. return SpecialLinks;
  217. }
  218. /// <summary>
  219. /// 此公有方法从本网页的链接中提取一定数量的链接,该链接的文字满足某正则式
  220. /// </summary>
  221. /// <param name="pattern">正则式</param>
  222. /// <param name="count">返回的链接的个数</param>
  223. /// <returns>List<Link></returns>
  224. public List<Link> getSpecialLinksByText(string pattern, int count)
  225. {
  226. if (m_links.Count == 0) getLinks();
  227. List<Link> SpecialLinks = new List<Link>();
  228. List<Link>.Enumerator i;
  229. i = m_links.GetEnumerator();
  230. int cnt = 0;
  231. while (i.MoveNext() && cnt < count)
  232. {
  233. if (new Regex(pattern, RegexOptions.Multiline | RegexOptions.IgnoreCase).Match(i.Current.Text).Success)
  234. {
  235. SpecialLinks.Add(i.Current);
  236. cnt++;
  237. }
  238. }
  239. return SpecialLinks;
  240. }
  241. /// <summary>
  242. /// 这公有方法提取本网页的纯文本中满足某正则式的文字
  243. /// </summary>
  244. /// <param name="pattern">正则式</param>
  245. /// <returns>返回文字</returns>
  246. public string getSpecialWords(string pattern)
  247. {
  248. if (m_outstr == "") getContext(Int16.MaxValue);
  249. Regex regex = new Regex(pattern, RegexOptions.Multiline | RegexOptions.IgnoreCase);
  250. Match mc = regex.Match(m_outstr);
  251. if (mc.Success)
  252. return mc.Groups[1].Value;
  253. return string.Empty;
  254. }
  255. #endregion
  256. #region 构造函数
  257. private void Init(string _url)
  258. {
  259. try
  260. {
  261. m_uri = new Uri(_url);
  262. m_links = new List<Link>();
  263. m_html = "";
  264. m_outstr = "";
  265. m_title = "";
  266. m_good = true;
  267. if (_url.EndsWith(".rar") || _url.EndsWith(".dat") || _url.EndsWith(".msi"))
  268. {
  269. m_good = false;
  270. return;
  271. }
  272. HttpWebRequest rqst = (HttpWebRequest)WebRequest.Create(m_uri);
  273. rqst.AllowAutoRedirect = true;
  274. rqst.MaximumAutomaticRedirections = 3;
  275. rqst.UserAgent = "Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)";
  276. rqst.KeepAlive = true;
  277. rqst.Timeout = 10000;
  278. lock (WebPage.webcookies)
  279. {
  280. if (WebPage.webcookies.ContainsKey(m_uri.Host))
  281. rqst.CookieContainer = WebPage.webcookies[m_uri.Host];
  282. else
  283. {
  284. CookieContainer cc = new CookieContainer();
  285. WebPage.webcookies[m_uri.Host] = cc;
  286. rqst.CookieContainer = cc;
  287. }
  288. }
  289. HttpWebResponse rsps = (HttpWebResponse)rqst.GetResponse();
  290. Stream sm = rsps.GetResponseStream();
  291. if (!rsps.ContentType.ToLower().StartsWith("text/") || rsps.ContentLength > 1 << 22)
  292. {
  293. rsps.Close();
  294. m_good = false;
  295. return;
  296. }
  297. Encoding cding = System.Text.Encoding.Default;
  298. string contenttype = rsps.ContentType.ToLower();
  299. int ix = contenttype.IndexOf("charset=");
  300. if (ix != -1)
  301. {
  302. try
  303. {
  304. cding = System.Text.Encoding.GetEncoding(rsps.ContentType.Substring(ix + "charset".Length + 1));
  305. }
  306. catch
  307. {
  308. cding = Encoding.Default;
  309. }
  310. //该处视情况而定 有的需要解码
  311. //m_html = HttpUtility.HtmlDecode(new StreamReader(sm, cding).ReadToEnd());
  312. m_html = new StreamReader(sm, cding).ReadToEnd();
  313. }
  314. else
  315. {
  316. //该处视情况而定 有的需要解码
  317. //m_html = HttpUtility.HtmlDecode(new StreamReader(sm, cding).ReadToEnd());
  318. m_html = new StreamReader(sm, cding).ReadToEnd();
  319. Regex regex = new Regex("charset=(?<cding>[^=]+)?\"", RegexOptions.IgnoreCase);
  320. string strcding = regex.Match(m_html).Groups["cding"].Value;
  321. try
  322. {
  323. cding = Encoding.GetEncoding(strcding);
  324. }
  325. catch
  326. {
  327. cding = Encoding.Default;
  328. }
  329. byte[] bytes = Encoding.Default.GetBytes(m_html.ToCharArray());
  330. m_html = cding.GetString(bytes);
  331. if (m_html.Split('?').Length > 100)
  332. {
  333. m_html = Encoding.Default.GetString(bytes);
  334. }
  335. }
  336. m_pagesize = m_html.Length;
  337. m_uri = rsps.ResponseUri;
  338. rsps.Close();
  339. }
  340. catch (Exception ex)
  341. {
  342. }
  343. }
  344. public WebPage(string _url)
  345. {
  346. string uurl = "";
  347. try
  348. {
  349. uurl = Uri.UnescapeDataString(_url);
  350. _url = uurl;
  351. }
  352. catch { };
  353. Init(_url);
  354. }
  355. #endregion
  356. }

调用

  1. WebPage webInfo = new WebPage("网址");
  2. webInfo.Context;//不包含html标签的所有内容
  3. webInfo.M_html;//包含html标签的内容
  4. ...参考属性

Original:http://blog.csdn.net/yysyangyangyangshan/article/details/6661886