从 html 代码中解析链接的正则表达式

Posted

技术标签:

【中文标题】从 html 代码中解析链接的正则表达式【英文标题】:regular expression to parse links from html code 【发布时间】:2010-12-24 22:03:44 【问题描述】:

我正在研究一种接受字符串(html 代码)并返回包含 in 中包含的所有链接的数组的方法。

我已经看到了一些选项,例如 html 能力包,但它似乎比这个项目要求的要复杂一些

我也对使用正则表达式感兴趣,因为我没有太多的经验,我认为这将是一个很好的学习机会。

到目前为止我的代码是

 WebClient client = new WebClient();
            string htmlCode = client.DownloadString(p);
            Regex exp = new Regex(@"http://(www\.)?([^\.]+)\.com", RegexOptions.IgnoreCase);
            string[] test = exp.Split(htmlCode);

但我没有得到我想要的结果,因为我仍在处理正则表达式

我正在寻找的 sudo 代码是“

【问题讨论】:

虽然不是答案,但这可能是您学习正则表达式时想要使用的工具:rubular.com 由于我们提供有用的自学正则表达式工具,我想说我是The Regex Coach 的忠实粉丝。它看起来比 Rubular 功能更丰富(单步执行和树功能特别有用),但显然需要下载和安装,而不是基于浏览器。 必填链接:***.com/questions/1732348/… 【参考方案1】:

如果您正在寻找一个万无一失的解决方案,正则表达式不是您的答案。由于 HTML 语言的复杂性,它们从根本上受到限制,不能用于可靠地从 HTML 文件中解析出链接或其他标签。

长篇版:http://blogs.msdn.com/jaredpar/archive/2008/10/15/regular-expression-limitations.aspx

相反,您需要使用实际的 HTML DOM API 来解析链接。

【讨论】:

+1。具体来说,正则表达式和识别正则语言。 HTML 是一种上下文无关语言,因此您需要比正则表达式语言更强大的解析器才能使其 100% 正确。 (en.wikipedia.org/wiki/Chomsky_hierarchy) 可能会得到一个基本正确的解决方案,特别是如果您的正则表达式引擎有一些超出严格正则语法的扩展。但是了解正则表达式的局限性非常重要。我见过很多由于不了解这一点而导致的安全问题。【参考方案2】:

正则表达式不是 HTML 的最佳选择。

查看之前的问题:

When is it wise to use regular expressions with HTML? Regexp that matches all the text content of a HTML input

相反,你想要一些已经知道如何解析 DOM 的东西;否则,你就是在重新发明***。

【讨论】:

【参考方案3】:

其他用户可能会告诉您“不,停止!正则表达式不应该与 HTML 混合!这就像混合漂白剂和氨水!”。这个建议有很多智慧,但这不是全部。

事实上,正则表达式在收集常用格式的链接时工作得很好。但是,更好的方法是使用专门的工具来处理这类事情,例如 HtmlAgilityPack。

如果您使用正则表达式,您可能会匹配 99.9% 的链接,但您可能会错过罕见的意外极端情况或格式错误的 html 数据。

这是我整理的一个函数,它使用 HtmlAgilityPack 来满足您的要求:

    private static IEnumerable<string> DocumentLinks(string sourceHtml)
    
        HtmlDocument sourceDocument = new HtmlDocument();

        sourceDocument.LoadHtml(sourceHtml);

        return (IEnumerable<string>)sourceDocument.DocumentNode
            .SelectNodes("//a[@href!='#']")
                .Select(n => n.GetAttributeValue("href",""));

    

此函数创建一个新的 HtmlAgilityPack.HtmlDocument,将包含 HTML 的字符串加载到其中,然后使用 xpath 查询“//a[@href!='#']”来选择页面上的所有链接不要指向“#”。然后我使用 LINQ 扩展 Select 将 HtmlNodeCollection 转换为包含 href 属性值的字符串列表 - 链接指向的位置。

这是一个使用示例:

        List<string> links = 
            DocumentLinks((new WebClient())
                .DownloadString("http://google.com")).ToList();

        Debugger.Break();

这应该比正则表达式有效得多。

【讨论】:

【参考方案4】:

您可以查找类似于 http/https 架构的 url 的任何内容。这不是 HTML 证明,但它会给你一些看起来像 http URL 的东西,我怀疑这是你需要的。您可以添加更多 sachems 和域。 正则表达式查找类似于 URL“in”href 属性的内容(不严格)。

class Program 
    static void Main(string[] args) 
        const string pattern = @"href=[""'](?<url>(http|https)://[^/]*?\.(com|org|net|gov))(/.*)?[""']";
        var regex = new Regex(pattern);
        var urls = new string[]  
            "href='http://company.com'",
            "href=\"https://company.com\"",
            "href='http://company.org'",
            "href='http://company.org/'",
            "href='http://company.org/path'",
        ;

        foreach (var url in urls) 
            Match match = regex.Match(url);
            if (match.Success) 
                Console.WriteLine("0 -> 1", url, match.Groups["url"].Value);
            
        
    

输出:

href='http://company.com' -> http://company.com href="https://company.com" -> https://company.com href='http://company.org' -> http://company.org href='http://company.org/' -> http://company.org href='http://company.org/path' -> http://company.org

【讨论】:

以上是关于从 html 代码中解析链接的正则表达式的主要内容,如果未能解决你的问题,请参考以下文章

用于解析网页链接的正则表达式?

html文本中链接的正则表达式

Python从零开始写爬虫-2 使用正则表达式解析HTML

正则表达式帮助python找到链接

使用正则表达式替代 HTML 解析

python爬虫之解析库正则表达式