如何使用htmlagilitypack从html文档中提取所有链接?

时间:2015-06-07 11:48:01

标签: c# .net winforms

HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
            doc.LoadHtml(s1);

foreach (HtmlNode link in doc.DocumentNode.SelectNodes("//a[@href]"))
                {
                    count++;
                    HtmlAttribute att = link.Attributes["href"];
                    if (att.Value.StartsWith("http") && !listBox1.Items.Contains(att.Value))
                        listBox1.Items.Add(att.Value);
                }

我得到了151个结果,但实际上有超过300个。 在许多情况下,它发现了链接,其中包含多个链接,例如:

href="http://www.test.com dfsdfgfg https://www.test1.com 656567 http://test2.com

在这种情况下,我需要打破它,这样它会显示我并算作3个链接,而不是一个。 我试图将att.Value.StartsWith(“http”)更改为att.Value.Contains(“http”),但这不是解决方案。

1 个答案:

答案 0 :(得分:4)

以下是您可以做的事情:

foreach (HtmlNode link in doc.DocumentNode.SelectNodes("//a[@href]"))
                {
                    count++;
                    HtmlAttribute att = link.Attributes["href"];
                    foreach (var link in att.Value.Split(' ')) {
                       if (link.StartsWith("http") && !listBox1.Items.Contains(link))
                           listBox1.Items.Add(link);
                    }
                }

这将在HTML文档的<a href="...">标记中找到链接。如果你需要找到所有链接(包括javascript代码,样式等),你可以使用正则表达式,如下所示:

 private static readonly Regex cHttpUrlsRegex = new Regex(@"(?<url>((http|https):[/][/]|www.)([a-z]|[A-Z]|[0-9]|[_/.=&?%-]|[~])*)", RegexOptions.IgnoreCase);

        public static IEnumerable<string> ExtractHttpUrls(string aText, string aMatch = null)
        {
            if (String.IsNullOrEmpty(aText)) yield break;
            var matches = cHttpUrlsRegex.Matches(aText);
            var vMatcher = aMatch == null ? null : new Regex(aMatch);
            foreach (Match match in matches)
            {
                var vUrl = HttpUtility.UrlDecode(match.Groups["url"].Value);
                if (vMatcher == null || vMatcher.IsMatch(vUrl))
                    yield return vUrl;
            }
        }

foreach (var link ExtractHttpUrls(s1))
                {
                    count++;
                       if (link.StartsWith("http") && !listBox1.Items.Contains(link))
                           listBox1.Items.Add(link);
                }