/// <summary> /// 处理UrlDictionary,筛选+做的是减法 /// </summary> /// <param name="args"></param> /// <param name="patternStr"></param> private static void CustomParseLink_MainList(CustomParseLinkEvent3Args args, string patternStr) { Dictionary<string, string> temp = new Dictionary<string, string>(); foreach (var item in args.UrlDictionary) { string href = item.Key; string text = item.Value; if (!string.IsNullOrEmpty(href)) { Regex regex = new Regex(patternStr, RegexOptions.IgnoreCase);//忽略大小写 Match mat = regex.Match(href); if (mat.Success) { temp.Add(href, text); } } } args.UrlDictionary = temp; }
/// <summary> /// 处理Html,重新过滤+做的是加法 /// </summary> /// <param name="args"></param> /// <param name="patternStr"></param> /// <param name="groupIndex"></param> private static void CustomParseLink_NextPageSdau(CustomParseLinkEvent3Args args, string patternStr, int groupIndex) { string url = ""; if (args != null && !string.IsNullOrEmpty(args.Html)) { Regex regex = new Regex(patternStr, RegexOptions.IgnoreCase);//忽略大小写 Match mat = regex.Match(args.Html); if (mat.Success) { url = mat.Groups[groupIndex].Value; var baseUri = new Uri(args.UrlInfo.UrlString); Uri currentUri = url.StartsWith("http", StringComparison.OrdinalIgnoreCase) ? new Uri(url) : new Uri(baseUri, url);//根据指定的基 URI 和相对 URI 字符串,初始化 System.Uri 类的新实例。 //如果不包含http,则认为超链接是相对路径,根据baseUrl建立绝对路径 url = currentUri.AbsoluteUri; //Console.WriteLine("######" + url + "######"); args.UrlDictionary.Add(url, Guid.NewGuid().ToString()); } } //return args.UrlDictionary; }
private static void CustomParseLink_MainListMode2(CustomParseLinkEvent3Args args, string kDetailPattern, int groupIndex) { string url = ""; if (args != null && !string.IsNullOrEmpty(args.Html)) { MatchCollection mat_k = Regex.Matches(args.Html, kDetailPattern, RegexOptions.IgnoreCase); foreach (Match item in mat_k) { if (item.Success) { url = item.Groups[groupIndex].Value; var baseUri = new Uri(args.UrlInfo.UrlString); Uri currentUri = url.StartsWith("http", StringComparison.OrdinalIgnoreCase) ? new Uri(url) : new Uri(baseUri, url);//根据指定的基 URI 和相对 URI 字符串,初始化 System.Uri 类的新实例。 //如果不包含http,则认为超链接是相对路径,根据baseUrl建立绝对路径 url = currentUri.AbsoluteUri; //Console.WriteLine("######" + url + "######"); args.UrlDictionary.Add(url, Guid.NewGuid().ToString()); } } } }
private static void Master_CustomParseLinkEvent3(CustomParseLinkEvent3Args args) { #region // #region 可以进一步修改 //if (isDetailMode2 == true) //{ // CustomParseLink_MainList(args, "今天天气好晴朗,又是刮风又是下雨。");//什么都不匹配 // CustomParseLink_MainListMode2(args, configModel.kDetailPattern, 0); //} //else //{ // CustomParseLink_MainList(args, configModel.kDetailPattern);//什么都不匹配 //} #endregion // CustomParseLink_MainList(args, "什么都不匹配什么都不匹配什么都不匹配什么都不匹配");//什么都不匹配 CustomParseLink_MainListMode2(args, configModel.kDetailPattern, 0); CustomParseLink_NextPageSdau(args, configModel.kNextPagePattern, 1);//下一页 #endregion #region SDAU //CustomParseLink_MainList(args, "(view).+?([0-9]{5})");//去除,下一步,拼写一个大的正则表达式就好 //CustomParseLink_NextPageSdau(args, "<a .+ href='(.+)'>下一页</a>", 1);//添加,下一步,拼写一个大的正则表达式就好 #endregion #region 北京市地震局 //CustomParseLink_MainList(args, "今天天气好晴朗,又是刮风又是下雨");//什么都不匹配 //CustomParseLink_NextPageSdau(args, "•<A href=\"(/manage/html/[\\d\\w]{32}/_content/\\d{2}_\\d{2}/\\d{2}/\\d+\\.html)\"", 1);//详细页 //CustomParseLink_NextPageSdau(args, "<a href=\"(index_\\d+.html)\">下一页</a>", 1);//下一页 #endregion #region 上海民政 ////去除(保留符合正则的),下一步,拼写一个大的正则表达式就好 //CustomParseLink_MainList(args, @"/gb/shmzj/node4/node\d+/n\d{4}/u1ai\d{5}.html"); ////添加,下一步,拼写一个大的正则表达式就好 //CustomParseLink_NextPageSdau(args, "<a HREF=\"(/gb\\shmzj/node4/node\\d+/n\\d{4}/index\\d+\\.html)\" class=next>下一页</a>", 1); //<a href="(List.action\?[\w\d&=]+)">下一页</a> #endregion #region 陕西 ////去除,下一步,拼写一个大的正则表达式就好 //CustomParseLink_MainList(args, @"xg-xxgk-gk-[\d|-]+");//xg-xxgk-gk-[\d|-]+ ////添加,下一步,拼写一个大的正则表达式就好 //CustomParseLink_NextPageSdau(args, "<a href=\"(List.action\\?[\\w\\d&=]+)\">下一页</a>", 1); //<a href="(List.action\?[\w\d&=]+)">下一页</a> #endregion #region 上海 ////去除,下一步,拼写一个大的正则表达式就好 //CustomParseLink_MainList(args, @"detail1.jsp.*id=\d*"); ////添加,下一步,拼写一个大的正则表达式就好 //CustomParseLink_NextPageSdau(args, @"<A .*HREF=(.+) class.*>\s*下一页</A>", 1); #endregion #region 安居客 //CustomParseLink_MainList(args, "http://beijing.anjuke.com/prop/view/.*commsearch_p"); //CustomParseLink_NextPageSdau(args, "<a href='(.+)' class='aNxt'>下一页 ></a>", 1); //CustomParseLink_NextPageSdau(args, "http://beijing.anjuke.com/prop/view/.*commsearch_p", 0); #endregion }
/// <summary> /// The parse links. /// 超链接解析 /// 通用的超链接解析;没有针对特定的超链接解析暴露接口 /// </summary> /// <param name="urlInfo"> /// The url info. /// </param> /// <param name="html"> /// The html. /// </param> private void ParseLinks(UrlInfo urlInfo, string html) { //设置参数大于0,并且 url深度 大于等于 设置深度==》同时满足==》退出 //设置参数小于等于0,或者url深度 小于 设置深度(2)==》执行下面处理 if (this.Settings.Depth > 0 && urlInfo.Depth >= this.Settings.Depth) { return; } var urlDictionary = new Dictionary<string, string>();//<href,text> //http://([\w-]+\.)+[\w-]+(/[\w- ./?%&=]*)? Match match = Regex.Match(html, "(?i)<a .*?href=\"([^\"]+)\"[^>]*>(.*?)</a>");//原来的正则表达式"(?i)<a .*?href=\"([^\"]+)\"[^>]*>(.*?)</a>"超链接正则表达式 while (match.Success) { // 以 href 作为 key string urlKey = match.Groups[1].Value; // 以 text 作为 value string urlValue = Regex.Replace(match.Groups[2].Value, "(?i)<.*?>", string.Empty); urlDictionary[urlKey] = urlValue; match = match.NextMatch();//从上一个匹配结束的位置(即在上一个匹配字符之后的字符)开始返回一个包含下一个匹配结果的新 } //至此会得到一个urlDictionary[urlKey] = urlValue; //Kiwi:在这里添加自定义处理也不错,url+html==>url //至此出现两个问题:1、有些URL不是我们需要的,它们添加进来了 // 2、有由JS自动生成的url,这里没有获得,比如page.js,页面接受完数据后,浏览器执行js代码,生成页码条,嵌入到页面上 //自定义操作,我挖掘html,获得新URL加入到urlDictionary; // urlDictionary删除不必要的URL if (CustomParseLinkEvent3 != null) { CustomParseLinkEvent3Args linkArgs = new CustomParseLinkEvent3Args { UrlInfo = urlInfo, UrlDictionary = urlDictionary, Html = html };//1、urlInfo原始信息;2、初步解析后的html信息;3、初步解析得到的url集合 #region 被升级的代码 //CustomParseLinkEvent2的代码 //urlDictionary = CustomParseLinkEvent2(new CustomParseLinkEvent2Args //{ // UrlInfo = urlInfo, // UrlDictionary = urlDictionary, // Html = html //}); #endregion 被升级的代码 CustomParseLinkEvent3(linkArgs); urlDictionary = linkArgs.UrlDictionary; } foreach (var item in urlDictionary) { string href = item.Key; string text = item.Value; if (!string.IsNullOrEmpty(href)) { bool canBeAdd = true; if (this.Settings.EscapeLinks != null && this.Settings.EscapeLinks.Count > 0)//有忽略链接 { //(suffix:后缀;StringComparison.OrdinalIgnoreCase:忽略大小写,进行比较) if (this.Settings.EscapeLinks.Any(suffix => href.EndsWith(suffix, StringComparison.OrdinalIgnoreCase)))// 确定序列中的任何元素是否都满足条件。 //满足条件,不添加;即有满足忽略后缀的超链接,不添加 { canBeAdd = false; } } if (this.Settings.HrefKeywords != null && this.Settings.HrefKeywords.Count > 0)//有连接关键词 { if (!this.Settings.HrefKeywords.Any(href.Contains))//不包含关键字,不添加。原来关键字这么重要。 { canBeAdd = false; } } if (canBeAdd) { string url = href.Replace("%3f", "?") .Replace("%3d", "=") .Replace("%2f", "/") .Replace("&", "&"); if (string.IsNullOrEmpty(url) || url.StartsWith("#") || url.StartsWith("mailto:", StringComparison.OrdinalIgnoreCase) || url.StartsWith("javascript:", StringComparison.OrdinalIgnoreCase)) { continue; } var baseUri = new Uri(urlInfo.UrlString); Uri currentUri = url.StartsWith("http", StringComparison.OrdinalIgnoreCase) ? new Uri(url) : new Uri(baseUri, url);//根据指定的基 URI 和相对 URI 字符串,初始化 System.Uri 类的新实例。 //如果不包含http,则认为超链接是相对路径,根据baseUrl建立绝对路径 url = currentUri.AbsoluteUri; if (this.Settings.LockHost) { // 去除二级域名后,判断域名是否相等,相等则认为是同一个站点 // 例如:mail.pzcast.com 和 www.pzcast.com if (baseUri.Host.Split('.').Skip(1).Aggregate((a, b) => a + "." + b) != currentUri.Host.Split('.').Skip(1).Aggregate((a, b) => a + "." + b)) { continue; } } if (!this.IsMatchRegular(url))//如果不匹配 { continue; } #region addUrlEventArgs var addUrlEventArgs = new AddUrlEventArgs { Title = text, Depth = urlInfo.Depth + 1, Url = url }; if (this.AddUrlEvent != null && !this.AddUrlEvent(addUrlEventArgs)) { continue; } #endregion addUrlEventArgs //Kiwi:在这里添加一个事件处理自定义的url处理方法最好了 //经过上面的一系列处理,决定将url加入队列 UrlQueue.Instance.EnQueue(new UrlInfo(url) { Depth = urlInfo.Depth + 1 }); } } } }
/// <summary> /// The parse links. /// 超链接解析 /// 通用的超链接解析;没有针对特定的超链接解析暴露接口 /// </summary> /// <param name="urlInfo"> /// The url info. /// </param> /// <param name="html"> /// The html. /// </param> private void ParseLinks(UrlInfo urlInfo, string html) { //设置参数大于0,并且 url深度 大于等于 设置深度==》同时满足==》退出 //设置参数小于等于0,或者url深度 小于 设置深度(2)==》执行下面处理 if (this.Settings.Depth > 0 && urlInfo.Depth >= this.Settings.Depth) { return; } var urlDictionary = new Dictionary <string, string>(); //<href,text> //http://([\w-]+\.)+[\w-]+(/[\w- ./?%&=]*)? Match match = Regex.Match(html, "(?i)<a .*?href=\"([^\"]+)\"[^>]*>(.*?)</a>"); //原来的正则表达式"(?i)<a .*?href=\"([^\"]+)\"[^>]*>(.*?)</a>"超链接正则表达式 while (match.Success) { // 以 href 作为 key string urlKey = match.Groups[1].Value; // 以 text 作为 value string urlValue = Regex.Replace(match.Groups[2].Value, "(?i)<.*?>", string.Empty); urlDictionary[urlKey] = urlValue; match = match.NextMatch();//从上一个匹配结束的位置(即在上一个匹配字符之后的字符)开始返回一个包含下一个匹配结果的新 } //至此会得到一个urlDictionary[urlKey] = urlValue; //Kiwi:在这里添加自定义处理也不错,url+html==>url //至此出现两个问题:1、有些URL不是我们需要的,它们添加进来了 // 2、有由JS自动生成的url,这里没有获得,比如page.js,页面接受完数据后,浏览器执行js代码,生成页码条,嵌入到页面上 //自定义操作,我挖掘html,获得新URL加入到urlDictionary; // urlDictionary删除不必要的URL if (CustomParseLinkEvent3 != null) { CustomParseLinkEvent3Args linkArgs = new CustomParseLinkEvent3Args { UrlInfo = urlInfo, UrlDictionary = urlDictionary, Html = html };//1、urlInfo原始信息;2、初步解析后的html信息;3、初步解析得到的url集合 #region 被升级的代码 //CustomParseLinkEvent2的代码 //urlDictionary = CustomParseLinkEvent2(new CustomParseLinkEvent2Args //{ // UrlInfo = urlInfo, // UrlDictionary = urlDictionary, // Html = html //}); #endregion 被升级的代码 CustomParseLinkEvent3(linkArgs); urlDictionary = linkArgs.UrlDictionary; } foreach (var item in urlDictionary) { string href = item.Key; string text = item.Value; if (!string.IsNullOrEmpty(href)) { bool canBeAdd = true; if (this.Settings.EscapeLinks != null && this.Settings.EscapeLinks.Count > 0) //有忽略链接 { //(suffix:后缀;StringComparison.OrdinalIgnoreCase:忽略大小写,进行比较) if (this.Settings.EscapeLinks.Any(suffix => href.EndsWith(suffix, StringComparison.OrdinalIgnoreCase))) // 确定序列中的任何元素是否都满足条件。 //满足条件,不添加;即有满足忽略后缀的超链接,不添加 { canBeAdd = false; } } if (this.Settings.HrefKeywords != null && this.Settings.HrefKeywords.Count > 0) //有连接关键词 { if (!this.Settings.HrefKeywords.Any(href.Contains)) //不包含关键字,不添加。原来关键字这么重要。 { canBeAdd = false; } } if (canBeAdd) { string url = href.Replace("%3f", "?") .Replace("%3d", "=") .Replace("%2f", "/") .Replace("&", "&"); if (string.IsNullOrEmpty(url) || url.StartsWith("#") || url.StartsWith("mailto:", StringComparison.OrdinalIgnoreCase) || url.StartsWith("javascript:", StringComparison.OrdinalIgnoreCase)) { continue; } var baseUri = new Uri(urlInfo.UrlString); Uri currentUri = url.StartsWith("http", StringComparison.OrdinalIgnoreCase) ? new Uri(url) : new Uri(baseUri, url); //根据指定的基 URI 和相对 URI 字符串,初始化 System.Uri 类的新实例。 //如果不包含http,则认为超链接是相对路径,根据baseUrl建立绝对路径 url = currentUri.AbsoluteUri; if (this.Settings.LockHost) { // 去除二级域名后,判断域名是否相等,相等则认为是同一个站点 // 例如:mail.pzcast.com 和 www.pzcast.com if (baseUri.Host.Split('.').Skip(1).Aggregate((a, b) => a + "." + b) != currentUri.Host.Split('.').Skip(1).Aggregate((a, b) => a + "." + b)) { continue; } } if (!this.IsMatchRegular(url))//如果不匹配 { continue; } #region addUrlEventArgs var addUrlEventArgs = new AddUrlEventArgs { Title = text, Depth = urlInfo.Depth + 1, Url = url }; if (this.AddUrlEvent != null && !this.AddUrlEvent(addUrlEventArgs)) { continue; } #endregion addUrlEventArgs //Kiwi:在这里添加一个事件处理自定义的url处理方法最好了 //经过上面的一系列处理,决定将url加入队列 UrlQueue.Instance.EnQueue(new UrlInfo(url) { Depth = urlInfo.Depth + 1 }); } } } }