【发布时间】:2010-09-12 11:29:33
【问题描述】:
是否有内置的 dll 可以为我提供来自字符串的链接列表。我想发送一个带有有效 html 的字符串并让它解析所有链接。我似乎记得 .net 或非托管库中内置了一些东西。
我发现了几个看起来很有前途的开源项目,但我认为有一个内置模块。如果不是,我可能不得不使用其中之一。如果没有必要,我现在只是不想要外部依赖。
【问题讨论】:
是否有内置的 dll 可以为我提供来自字符串的链接列表。我想发送一个带有有效 html 的字符串并让它解析所有链接。我似乎记得 .net 或非托管库中内置了一些东西。
我发现了几个看起来很有前途的开源项目,但我认为有一个内置模块。如果不是,我可能不得不使用其中之一。如果没有必要,我现在只是不想要外部依赖。
【问题讨论】:
我不知道内置的任何内容,从您的问题来看,您正在寻找的内容有点模棱两可。你想要整个锚标记,还是只需要 href 属性中的 URL?
如果您有格式良好的 XHtml,您可能可以使用 XmlReader 和 XPath 查询来查找所有锚标记 (<a>),然后点击地址的 href 属性。由于这不太可能,因此您最好使用 RegEx 来提取您想要的内容。
使用 RegEx,您可以执行以下操作:
List<Uri> findUris(string message)
{
string anchorPattern = "<a[\\s]+[^>]*?href[\\s]?=[\\s\\\"\']+(?<href>.*?)[\\\"\\']+.*?>(?<fileName>[^<]+|.*?)?<\\/a>";
MatchCollection matches = Regex.Matches(message, anchorPattern, RegexOptions.IgnorePatternWhitespace | RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.Compiled);
if (matches.Count > 0)
{
List<Uri> uris = new List<Uri>();
foreach (Match m in matches)
{
string url = m.Groups["url"].Value;
Uri testUri = null;
if (Uri.TryCreate(url, UriKind.RelativeOrAbsolute, out testUri))
{
uris.Add(testUri);
}
}
return uris;
}
return null;
}
请注意,我想检查 href 以确保地址作为有效的 Uri 确实有意义。如果您实际上不打算在任何地方追求链接,则可以消除这种情况。
【讨论】:
"<a.*href=[\"'](?<url>[^\"]+[.\\s]*)[\"'].*>(?<name>[^<]+[.\\s]*)</a>" 中提供的RegEx 在以下情况下会失败&lt;DIR&gt; <A HREF="..">..</A><BR>03/02/10 04:42PM [GMT] &lt;DIR&gt; <A HREF="/Incoming/tmp/">tmp</A>(它只捕获一个超链接,我从FTP 目录列表中获得了这个示例)。将其更改为以下正则表达式:string anchorPattern = @"<a[\s]+[^>]*?href[\s]?=[\s\""\']+(?<href>.*?)[\""\']+.*?>(?<fileName>[^<]+|.*?)?<\/a>"; 在我测试的任何情况下都有效。
我认为没有内置库,但 Html Agility Pack 对于您想做的事情很受欢迎。
使用原始 .NET 框架并且没有外部依赖项的方法是使用正则表达式来查找字符串中的所有“a”标签。您可能需要处理很多边缘情况。例如 href = "http://url" vs href=http://url 等
【讨论】:
SubSonic.Sugar.Web.ScrapeLinks 似乎做了你想要的一部分,但是它从 url 中获取 html,而不是从字符串中。你可以查看他们的实现here。
【讨论】:
Google 给了我这个模块:http://www.majestic12.co.uk/projects/html_parser.php
似乎是 .NET 的 HTML 解析器。
【讨论】:
【讨论】: