2010-02-11 98 views
36

我正在一个小爱好项目上工作。我已经编写了代码来获取URL,下载标题并返回MIME类型/内容类型。获取HTML网页上的所有链接

然而,在此之前的一步是一个IM卡 - 我需要找回基于标签内页上的所有URL的内容,并在引号,即

... 
<link rel='shortcut icon' href="/static/favicon.ico" type="image/x-icon" /> 
... 

会发现图标链接。

在.net库中有没有什么有用的东西,或者这将不得不成为正则表达式的情况?

+11

我得到一个奇怪的感觉,在HTML敏捷性包是去... – jball 2010-02-11 23:01:35

回答

54

我会看看使用Html Agility Pack

这里有一个例子直接从他们的榜样页面上如何找到一个页面中的所有链接:

HtmlWeb hw = new HtmlWeb(); 
HtmlDocument doc = hw.Load(/* url */); 
foreach(HtmlNode link in doc.DocumentNode.SelectNodes("//a[@href]")) 
{ 

} 
+0

XPath的安永的方式演示 - 我喜欢它! – maxp 2010-02-11 23:05:54

+4

'DocumentElement'应该替换为'DocumentNode' – HadiRj 2015-10-06 06:12:15

+0

只是想补充一点,如果你试图加载的网站有一些gzip压缩,它会在'hw.Load'上抛出一个异常:''''gzip'不是支持的编码名称有关定义自定义编码的信息,请参阅Encoding.RegisterProvider方法的文档。找到解决方法[此处](https://stackoverflow.com/a/36220920/6178243) – 2017-06-20 20:16:19

14

没有内置到BCL什么,但幸运的是,你可以使用HTML Agility Pack做到这一点任务很简单。

至于你的具体问题,请参阅Easily extracting links from a snippet of html with HtmlAgilityPack

private List<string> ExtractAllAHrefTags(HtmlDocument htmlSnippet) 
{ 
    List<string> hrefTags = new List<string>(); 

    foreach (HtmlNode link in htmlSnippet.DocumentNode.SelectNodes("//a[@href]")) 
    { 
     HtmlAttribute att = link.Attributes["href"]; 
     hrefTags.Add(att.Value); 
    } 

    return hrefTags; 
} 
+2

这可以完成更简单的使用LINQ – SLaks 2010-02-11 23:05:55

+5

我不同意基于LINQ的方法比较简单声明式是的功能性绝对简单两种解决方案的简单性相同 – 2010-02-11 23:14:51

+0

XPath应该使用较少的内存 – 2014-11-18 18:01:59

31

您需要使用HTML Agility Pack

例如:

var doc = new HtmlWeb().Load(url); 
var linkTags = doc.DocumentNode.Descendants("link"); 
var linkedPages = doc.DocumentNode.Descendants("a") 
            .Select(a => a.GetAttributeValue("href", null)) 
            .Where(u => !String.IsNullOrEmpty(u)); 
相关问题