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

C# C转换HTML字符串中的相对绝对链接,c#,html,regex,parsing,url,C#,Html,Regex,Parsing,Url,我正在镜像一些内部网站以进行备份。到目前为止,我基本上使用以下c代码: System.Net.WebClient client = new System.Net.WebClient(); byte[] dl = client.DownloadData(url); 这基本上只是下载html并将其放入字节数组中。这就是我想要的。然而,问题是html中的链接大部分时间是相对的,而不是绝对的 我基本上想在相对链接之前附加任何完整的内容,以便将其转换为将重定向到原始内容的绝对链接。我基本上只关心href

我正在镜像一些内部网站以进行备份。到目前为止,我基本上使用以下c代码:

System.Net.WebClient client = new System.Net.WebClient();
byte[] dl = client.DownloadData(url);
这基本上只是下载html并将其放入字节数组中。这就是我想要的。然而,问题是html中的链接大部分时间是相对的,而不是绝对的

我基本上想在相对链接之前附加任何完整的内容,以便将其转换为将重定向到原始内容的绝对链接。我基本上只关心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);
}

我认为url是字符串类型的。使用Uri,而使用指向域的基本Uri:

Uri baseUri = new Uri("http://domain.is");
Uri myUri = new Uri(baseUri, url);

System.Net.WebClient client = new System.Net.WebClient();
byte[] dl = client.DownloadData(myUri);

虽然这可能不是最稳健的解决方案,但它应该完成这项工作

var host = "http://domain.is";
var someHtml = @"
<a href=""/some/relative"">Relative</a>
<img src=""/some/relative"" />
<a href=""http://domain.is/some/absolute"">Absolute</a>
<img src=""http://domain.is/some/absolute"" />
";


someHtml = someHtml.Replace("src=\"" + host,"src=\"");
someHtml = someHtml.Replace("href=\"" + host,"src=\"");
someHtml = someHtml.Replace("src=\"","src=\"" + host);
someHtml = someHtml.Replace("href=\"","src=\"" + host);

您应该使用Htmlagibility pack加载HTML,使用它访问所有的HREF,然后根据需要使用Uri类从相对转换为绝对

例如,请参见

,您可以使用。你可以沿着这些未经测试的路线做一些事情:

加载url 选择所有链接 将链接加载到中,并测试它是否是相对的 将其转换为绝对值 使用新的链接更新链接值 uri 保存文件 以下是几个例子:


最可靠的解决方案是按照其他人的建议使用。但是,使用正则表达式的合理解决方案可以使用接受委托的重载,如下所示:

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);
上面的示例搜索名为src和href的属性,这些属性包含以正斜杠开头的双引号值。对于每个匹配,静态方法用于确定该值是否为有效的相对uri

请注意,此解决方案不处理单引号的属性值,当然也不适用于具有未引号值的格式不良的HTML

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;
基于正则表达式的方法可能未经测试,可映射到:

        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);
我还建议不要在这里使用正则表达式,而是对一些使用DOM的代码应用Uri技巧,如果是xhtml,可能是XmlDocument,否则是HTML Agility Pack,查看所有的//@src或//@href属性。

只需使用此函数即可

'# converts relative URL ro Absolute URI
    Function RelativeToAbsoluteUrl(ByVal baseURI As Uri, ByVal RelativeUrl As String) As Uri
        ' get action tags, relative or absolute
        Dim uriReturn As Uri = New Uri(RelativeUrl, UriKind.RelativeOrAbsolute)
        ' Make it absolute if it's relative
        If Not uriReturn.IsAbsoluteUri Then
            Dim baseUrl As Uri = baseURI
            uriReturn = New Uri(baseUrl, uriReturn)
        End If
        Return uriReturn
    End Function
简单函数


我知道这是一个比较老的问题,但我知道如何用一个相当简单的正则表达式来实现它。它对我很有效。它处理http/https以及根相对和当前目录相对

var host = "http://www.google.com/";
var baseUrl = host + "images/";
var html = "<html><head></head><body><img src=\"/images/srpr/logo3w.png\" /><br /><img src=\"srpr/logo3w.png\" /></body></html>";
var regex = "(?<=(?:href|src)=\")(?!https?://)(?<url>[^\"]+)";
html = Regex.Replace(
    html,
    regex,
    match => match.Groups["url"].Value.StartsWith("/")
        ? host + match.Groups["url"].Value.Substring(1)
        : baseUrl + match.Groups["url"].Value);

这就是您要查找的内容,此代码段可以在任何HTML代码中将所有相对URL转换为绝对URL:

Private Function ConvertALLrelativeLinksToAbsoluteUri(ByVal html As String, ByVal PageURL As String)
    Dim result As String = Nothing
    ' Getting all Href
    Dim opt As New RegexOptions
    Dim XpHref As New Regex("(href="".*?"")", RegexOptions.IgnoreCase)
    Dim i As Integer
    Dim NewSTR As String = html
    For i = 0 To XpHref.Matches(html).Count - 1
        Application.DoEvents()
        Dim Oldurl As String = Nothing
        Dim OldHREF As String = Nothing
        Dim MainURL As New Uri(PageURL)
        OldHREF = XpHref.Matches(html).Item(i).Value
        Oldurl = OldHREF.Replace("href=", "").Replace("HREF=", "").Replace("""", "")
        Dim NEWURL As New Uri(MainURL, Oldurl)
        Dim NewHREF As String = "href=""" & NEWURL.AbsoluteUri & """"
        NewSTR = NewSTR.Replace(OldHREF, NewHREF)
    Next
    html = NewSTR
    Dim XpSRC As New Regex("(src="".*?"")", RegexOptions.IgnoreCase)
    For i = 0 To XpSRC.Matches(html).Count - 1
        Application.DoEvents()
        Dim Oldurl As String = Nothing
        Dim OldHREF As String = Nothing
        Dim MainURL As New Uri(PageURL)
        OldHREF = XpSRC.Matches(html).Item(i).Value
        Oldurl = OldHREF.Replace("src=", "").Replace("src=", "").Replace("""", "")
        Dim NEWURL As New Uri(MainURL, Oldurl)
        Dim NewHREF As String = "src=""" & NEWURL.AbsoluteUri & """"
        NewSTR = NewSTR.Replace(OldHREF, NewHREF)
    Next
    Return NewSTR
End Function

这是否会将myUri的html中的链接从相对更改为绝对,或者这只是使用WebClient的更好实践?我添加了一个编辑,至少在我的几个测试用例中可以工作。看看regex的内容,它看起来相当相似,但您的代码看起来要复杂得多。老实说,我从来没有使用过MatchEvaluator和代理工具;您的代码更好吗?使用MatchEvaluator可以极大地简化正则表达式模式,并使用更健壮的Uri.TryCreate方法。匹配所有可能URI的正则表达式将非常复杂。我确实尝试了您的示例,但似乎有一个bug。如果我有一个baseUrl作为http://ww.baseurl.com/somedir 我尝试使用您的方法创建一个绝对路径adding/login.php,我得到http://ww.baseurl.com/login.php 而不是http://ww.baseurl.com/somedir/login.php
Private Function ConvertALLrelativeLinksToAbsoluteUri(ByVal html As String, ByVal PageURL As String)
    Dim result As String = Nothing
    ' Getting all Href
    Dim opt As New RegexOptions
    Dim XpHref As New Regex("(href="".*?"")", RegexOptions.IgnoreCase)
    Dim i As Integer
    Dim NewSTR As String = html
    For i = 0 To XpHref.Matches(html).Count - 1
        Application.DoEvents()
        Dim Oldurl As String = Nothing
        Dim OldHREF As String = Nothing
        Dim MainURL As New Uri(PageURL)
        OldHREF = XpHref.Matches(html).Item(i).Value
        Oldurl = OldHREF.Replace("href=", "").Replace("HREF=", "").Replace("""", "")
        Dim NEWURL As New Uri(MainURL, Oldurl)
        Dim NewHREF As String = "href=""" & NEWURL.AbsoluteUri & """"
        NewSTR = NewSTR.Replace(OldHREF, NewHREF)
    Next
    html = NewSTR
    Dim XpSRC As New Regex("(src="".*?"")", RegexOptions.IgnoreCase)
    For i = 0 To XpSRC.Matches(html).Count - 1
        Application.DoEvents()
        Dim Oldurl As String = Nothing
        Dim OldHREF As String = Nothing
        Dim MainURL As New Uri(PageURL)
        OldHREF = XpSRC.Matches(html).Item(i).Value
        Oldurl = OldHREF.Replace("src=", "").Replace("src=", "").Replace("""", "")
        Dim NEWURL As New Uri(MainURL, Oldurl)
        Dim NewHREF As String = "src=""" & NEWURL.AbsoluteUri & """"
        NewSTR = NewSTR.Replace(OldHREF, NewHREF)
    Next
    Return NewSTR
End Function