Относительно абсолютных путей в HTML

Мне нужно создать информационный бюллетень по URL. Для этого я:

  1. Создайте WebClient.
  2. Используйте метод WebClient DownloadData, чтобы получить источник страницы в байтовом массиве;
  3. Получите строку из байтового массива source-html и установите ее в содержание информационного бюллетеня.

Однако у меня проблемы с путями. Источники всех элементов были относительными (/img/welcome.png), но мне нужен абсолютный, например http://www.example.com/img/welcome.png.

Как я могу это сделать?


person Alex M    schedule 27.04.2010    source источник


Ответы (5)


Одним из возможных способов решения этой задачи является использование библиотеки HtmlAgilityPack.

Пример (исправить ссылки):

WebClient client = new WebClient();
byte[] requestHTML = client.DownloadData(sourceUrl);
string sourceHTML = new UTF8Encoding().GetString(requestHTML);

HtmlDocument htmlDoc = new HtmlDocument();
htmlDoc.LoadHtml(sourceHTML);

foreach (HtmlNode link in htmlDoc.DocumentNode.SelectNodes("//a[@href]"))
{
    if (!string.IsNullOrEmpty(link.Attributes["href"].Value))
    {
        HtmlAttribute att = link.Attributes["href"];
        att.Value = this.AbsoluteUrlByRelative(att.Value);
    }
}
person Alex M    schedule 27.04.2010
comment
Мой сценарий не находит этого. - person ram4nd; 06.05.2012

если запрос приходит с вашего сайта (ссылки на те же домены), вы можете использовать это:

new Uri(Request.Uri, "/img/welcome.png").ToString();

Если вы используете не веб-приложение или хотите жестко закодировать доменное имя:

new Uri("http://www.mysite.com", "/img/welcome.png").ToString();
person Artiom Chilaru    schedule 27.04.2010
comment
Мне нужно заменить все элементы src и href в html, что я получаю не только по одному пути. - person Alex M; 27.04.2010

У вас есть несколько вариантов:

  1. Вы можете преобразовать свой байтовый массив в строку и найти замену.
  2. Вы можете создать объект DOM, преобразовать массив байтов в строку, загрузить его и добавить значение к атрибутам, где это необходимо (в основном вы ищете любой атрибут src, href, в котором нет http: или https:).
    Console.Write(ControlChars.Cr + "Please enter a Url(for example, http://www.msn.com): ")
    Dim remoteUrl As String = Console.ReadLine()
    Dim myWebClient As New WebClient()
    Console.WriteLine(("Downloading " + remoteUrl))
    Dim myDatabuffer As Byte() = myWebClient.DownloadData(remoteUrl)
    Dim download As String = Encoding.ASCII.GetString(myDataBuffer)
    download.Replace("src=""/", "src=""" & remoteUrl & "/")
    download.Replace("href=""/", "href=""" & remoteUrl & "/")
    Console.WriteLine(download)
    Console.WriteLine("Download successful.")

Это супер-надуманный вариант, и на самом деле основная его тяжесть взята непосредственно из: http://msdn.microsoft.com/en-us/library/xz398a3f.aspx, но он иллюстрирует основной принцип метода 1.

person Gabriel    schedule 27.04.2010
comment
Спасибо, я знаю такой способ, но я надеялся, что есть более простой способ сделать это =) - person Alex M; 27.04.2010

Просто используйте эту функцию

'# 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
person Smith    schedule 20.08.2011

Вместо разрешения / завершения относительных путей вы можете попытаться установить базовый элемент с помощью href-attrib = исходный baseURI, о котором идет речь.

Помещенные как первый дочерний элемент элемента заголовка, все последующие относительные пути должны разрешаться браузером, чтобы указывать на исходное место назначения, а не на то, откуда находится / откуда документ (информационный бюллетень).

в firefox некоторые тавтологические (‹- в формальной логике) циклы получения / установки всех src / href-attribs возобновляются в том, что ПОЛНЫЕ пути записываются на все уровни (сериализованы) html-документа, таким образом, с возможностью сценария и сохранения ...:

var d=document;
var n= d.querySelectorAll('[src]'); // do the same for [href] ...
var i=0; var op ="";var ops="";
for (i=0;i<n.length;i++){op = op + n[i].src + "\n";ops=n[i].src;
n[i].src=ops;}
alert(op);

Конечно, url () - func базируется на элементе STYLE-Element (s, - для background-img или content-rules), а также в style-attrib на уровне узла и, в частности, url () - func -установленные значения src / href НЕ рассматриваются / не проверяются никаким из вышеперечисленных решений.

Таким образом, получение подходящего базового элемента Elem к действительному, проверенному состоянию (список совместимости) кажется мне более многообещающим.

person dos    schedule 27.08.2013