Przetwarzaj linki HTML za pomocą C #

Czy istnieje wbudowany dll, który da mi listę linków z łańcucha. Chcę wysłać ciąg znaków z prawidłowym kodem HTML i sprawić, aby przeanalizował wszystkie linki. Wydaje mi się, że pamiętam, że istnieje coś wbudowanego w .net lub niezarządzaną bibliotekę.

Znalazłem kilka projektów open source, które wyglądały obiecująco, ale myślałem, że istnieje wbudowany moduł. Jeśli nie, być może będę musiał użyć jednego z nich. Po prostu nie chciałem w tym momencie zewnętrznej zależności, jeśli nie było to konieczne.

questionAnswers(5)

Google daje mi ten moduł:http://www.majestic12.co.uk/projects/html_parser.php

Wydaje się być parserem HTML dla .NET.

Proste wyrażenie regularne -

@ "<a. *?>"

przekazane doRegex.Matches powinien robić to, czego potrzebujesz. Ten regex może wymagać drobnych poprawek, ale myślę, że jest dość blisko.

Nie jestem świadomy niczego wbudowanego i na podstawie twojego pytania jest to trochę dwuznaczne, czego dokładnie szukasz. Czy chcesz całego znacznika zakotwiczenia, czy tylko adresu URL z atrybutu href?

Jeśli masz dobrze sformatowany plik XHtml, możesz znaleźć rozwiązanie pozwalające na użycie XmlReader i zapytania XPath, aby znaleźć wszystkie znaczniki zakotwiczenia (<a>), a następnie naciśnij atrybut href dla adresu. Ponieważ jest to mało prawdopodobne, prawdopodobnie lepiej będzie korzystać z RegEx, aby obniżyć to, co chcesz.

Używając RegEx, możesz zrobić coś takiego:

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;
}

Zauważ, że chciałbym sprawdzić href, aby upewnić się, że adres rzeczywiście ma sens jako prawidłowy Uri. Możesz to wyeliminować, jeśli w rzeczywistości nie będziesz dążył do tego linku.

 CARLOS LOTH27 lip 2010, 20:21
+1 dla podania przykładu. Chciałbym jednak podkreślić, że RegEx podałeś w próbce"<a.*href=[\"'](?<url>[^\"]+[.\\s]*)[\"'].*>(?<name>[^<]+[.\\s]*)</a>" kończy się niepowodzeniem w następującym przypadku&lt;DIR&gt; <A HREF="..">..</A><BR>03/02/10 04:42PM [GMT] &lt;DIR&gt; <A HREF="/Incoming/tmp/">tmp</A> (przechwytuje tylko jedno hiperłącze, mam ten przykład z listy katalogów FTP). Zmiana na następujący RegEx:string anchorPattern = @"<a[\s]+[^>]*?href[\s]?=[\s\""\']+(?<href>.*?)[\""\']+.*?>(?<fileName>[^<]+|.*?)?<\/a>"; pracował w każdym przypadku testowałem.

Myślę, że nie ma wbudowanej biblioteki, aleHtml Agility Pack jest popularny ze względu na to, co chcesz robić.

Sposobem na zrobienie tego z surową strukturą .NET i brakiem zewnętrznych zależności byłoby użycie wyrażenia regularnego do znalezienia wszystkich znaczników „a” w łańcuchu. Być może musiałbyś zająć się wieloma przypadkami krawędzi. np. href = "http: // url"vs href =http: // url itp.

QuestionSolution

SubSonic.Sugar.Web.ScrapeLinks wydaje się, że robi część tego, co chcesz, jednak pobiera HTML z adresu URL, a nie z łańcucha. Możesz sprawdzić ich implementacjętutaj.

 Shaun Bowe23 wrz 2008, 20:55
To jest właśnie to, co chcę zrobić, więc to będzie dla mnie świetne. Nie do końca wbudowany, ale przynajmniej SubSonic prawdopodobnie miał pewien poziom testowania / użycia.
 Forgotten Semicolon11 lip 2011, 23:09
@Lasse V. Karlsen, gotowe.
 Lasse Vågsæther Karlsen11 lip 2011, 22:48
@Forgotten Czy masz szansę uratować tę odpowiedź, udostępniając nowe i działające linki?

yourAnswerToTheQuestion