C#转换HTML字符串中的相对于绝对链接

Gar*_*ary 8 html c# regex url parsing

我正在镜像一些内部网站以备份.截至目前我基本上使用这个c#代码:

System.Net.WebClient client = new System.Net.WebClient();
byte[] dl = client.DownloadData(url);
Run Code Online (Sandbox Code Playgroud)

这基本上只是将html下载到一个字节数组中.这就是我要的.然而问题是html中的链接大多数时间是相对的,而不是绝对的.

我基本上想要在相对链接之前附加任何完整的http://domain.is,以将其转换为将重定向到原始内容的绝对链接.我基本上只关心href =和src =.是否有正则表达式将涵盖一些基本情况?

编辑[我的尝试]:

public static string RelativeToAbsoluteURLS(string text, string absoluteUrl)
{
    if (String.IsNullOrEmpty(text))
    {
        return text;
    }

    String value = Regex.Replace(
        text, 
        "<(.*?)(src|href)=\"(?!http)(.*?)\"(.*?)>", 
        "<$1$2=\"" + absoluteUrl + "$3\"$4>", 
        RegexOptions.IgnoreCase | RegexOptions.Multiline);

    return value.Replace(absoluteUrl + "/", absoluteUrl);
}
Run Code Online (Sandbox Code Playgroud)

Nat*_*lch 9

最强大的解决方案是使用其他人建议的HTMLAgilityPack.但是,使用带有MatchEvaluator委托的Replace重载可以使用正则表达式的合理解决方案,如下所示:

var baseUri = new Uri("http://test.com");
var pattern = @"(?<name>src|href)=""(?<value>/[^""]*)""";
var matchEvaluator = new MatchEvaluator(
    match =>
    {
        var value = match.Groups["value"].Value;
        Uri uri;

        if (Uri.TryCreate(baseUri, value, out uri))
        {
            var name = match.Groups["name"].Value;
            return string.Format("{0}=\"{1}\"", name, uri.AbsoluteUri);
        }

        return null;
    });
var adjustedHtml = Regex.Replace(originalHtml, pattern, matchEvaluator);
Run Code Online (Sandbox Code Playgroud)

上面的示例搜索名为src和href的属性,这些属性包含以正斜杠开头的双引号值.对于每个匹配,静态Uri.TryCreate方法用于确定该值是否是有效的相对uri.

请注意,此解决方案不处理单引号属性值,当然不适用于带有不带引号的值的格式错误的HTML.


Ian*_*cer 5

您应该使用HtmlAgility包加载HTML,使用它访问所有href,然后根据需要使用Uri类从相对转换为绝对.

例如,参见http://blog.abodit.com/2010/03/a-simple-web-crawler-in-c-using-htmlagilitypack/


Mar*_*ell 5

Uri WebsiteImAt = new Uri(
       "http://www.w3schools.com/media/media_mimeref.asp?q=1&s=2,2#a");
string href = new Uri(WebsiteImAt, "/something/somethingelse/filename.asp")
       .AbsoluteUri;
string href2 = new Uri(WebsiteImAt, "something.asp").AbsoluteUri;
string href3 = new Uri(WebsiteImAt, "something").AbsoluteUri;
Run Code Online (Sandbox Code Playgroud)

与你的Regex基础的方法可能(未经测试)可映射到:

        String value = Regex.Replace(text, "<(.*?)(src|href)=\"(?!http)(.*?)\"(.*?)>", match => 
            "<" + match.Groups[1].Value + match.Groups[2].Value + "=\""
                + new Uri(WebsiteImAt, match.Groups[3].Value).AbsoluteUri + "\""
                + match.Groups[4].Value + ">",RegexOptions.IgnoreCase | RegexOptions.Multiline);
Run Code Online (Sandbox Code Playgroud)

我还应该建议不要Regex这里使用,而是将Uri技巧应用于使用DOM的一些代码,也许XmlDocument(如果是xhtml)或HTML Agility Pack(否则),查看所有//@src//@href属性.