Подтвердить что ты не робот

С# HttpWebRequest для получения списка каталогов

Мне нужен короткий фрагмент кода, чтобы получить список каталогов с HTTP-сервера.

Спасибо

4b9b3361

Ответ 1

Несколько важных соображений перед кодом:

  • HTTP-сервер должен быть настроен так, чтобы разрешить каталоги для нужных каталогов;
  • Поскольку списки каталогов являются нормальными страницами HTML, нет стандарта, который определяет формат списка каталогов;
  • В связи с рассмотрением 2 вы находитесь на земле, где вам нужно указать конкретный код для каждого сервера.

Мой выбор - использовать регулярные выражения. Это позволяет быстро разборе и настройке. Вы можете получить определенный шаблон регулярных выражений для каждого сайта, и таким образом у вас будет очень модульный подход. Используйте внешний источник для сопоставления URL-адресов шаблонам регулярных выражений, если вы планируете улучшить модуль синтаксического анализа с поддержкой новых сайтов без изменения исходного кода.

Пример печати списка каталогов из http://www.ibiblio.org/pub/

namespace Example
{
    using System;
    using System.Net;
    using System.IO;
    using System.Text.RegularExpressions;

    public class MyExample
    {
        public static string GetDirectoryListingRegexForUrl(string url)
        {
            if (url.Equals("http://www.ibiblio.org/pub/"))
            {
                return "<a href=\".*\">(?<name>.*)</a>";
            }
            throw new NotSupportedException();
        }
        public static void Main(String[] args)
        {
            string url = "http://www.ibiblio.org/pub/";
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
            using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
            {
                using (StreamReader reader = new StreamReader(response.GetResponseStream()))
                {
                    string html = reader.ReadToEnd();
                    Regex regex = new Regex(GetDirectoryListingRegexForUrl(url));
                    MatchCollection matches = regex.Matches(html);
                    if (matches.Count > 0)
                    {
                        foreach (Match match in matches)
                        {
                            if (match.Success)
                            {
                                Console.WriteLine(match.Groups["name"]);
                            }
                        }
                    }
                }
            }

            Console.ReadLine();
        }
    }
}

Ответ 2

Основное понимание:

Списки каталогов - это только HTML-страницы, созданные веб-сервером. Каждый веб-сервер генерирует эти HTML-страницы по-своему, потому что нет стандартного способа для веб-сервера для отображения этих каталогов.

Лучший способ получить список каталогов - это просто выполнить HTTP-запрос к URL-адресу, который вам нужен для списка каталогов, и попытаться разобрать и извлечь все ссылки из возвращаемого вами HTML.

Чтобы проанализировать HTML-ссылки, попробуйте использовать HTML Agility Pack.

Просмотр каталога:

Веб-сервер, на который вы хотите перечислить каталоги, должен включить просмотр каталогов, чтобы получить это HTML-представление файлов в своих каталогах. Таким образом, вы можете получить список каталогов, только если HTTP-сервер хочет, чтобы вы могли.

Быстрый пример пакета Agility Pack:

HtmlDocument doc = new HtmlDocument();
doc.Load(strURL);
foreach(HtmlNode link in doc.DocumentElement.SelectNodes("//[email protected]")
{
HtmlAttribute att = link"href";
//do something with att.Value;
}

Чистая альтернатива:

Если это возможно в вашей ситуации, более чистый метод - использовать предполагаемый протокол для списков каталогов, например, протокол передачи файлов (FTP), SFTP (FTP, например, через SSH) или FTPS (FTP через SSL).

Что делать, если просмотр каталогов не включен:

Если веб-сервер не включил просмотр каталогов, тогда нет простого способа получить список каталогов.

Лучшее, что вы могли бы сделать в этом случае - начать с заданного URL-адреса, следовать всем ссылкам HTML на той же странице и попытаться самостоятельно создать виртуальный список каталогов на основе относительных путей ресурсов на этих HTML-страницах, Это не даст вам полную информацию о том, какие файлы на самом деле находятся на веб-сервере.

Ответ 3

i только что был изменен выше и нашел это лучшее

public static class  GetallFilesFromHttp
{
    public static string GetDirectoryListingRegexForUrl(string url)
    {
        if (url.Equals("http://ServerDirPath/"))
        {
            return "\\\"([^\"]*)\\\""; 
        }
        throw new NotSupportedException();
    }
    public static void ListDiractory()
    {
        string url = "http://ServerDirPath/";
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
        using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
        {
            using (StreamReader reader = new StreamReader(response.GetResponseStream()))
            {
                string html = reader.ReadToEnd();

                Regex regex = new Regex(GetDirectoryListingRegexForUrl(url));
                MatchCollection matches = regex.Matches(html);
                if (matches.Count > 0)
                {
                    foreach (Match match in matches)
                    {
                        if (match.Success)
                        {
                            Console.WriteLine(match.ToString());
                        }
                    }
                }
            }
            Console.ReadLine();
        }
    }
}

Ответ 4

Спасибо за отличный пост. для меня картина ниже работала лучше.

<AHREF=\\"\S+\">(?<name>\S+)</A>

Я также тестировал его на http://regexhero.net/tester.

чтобы использовать его в коде С#, вы должны добавить больше обратных косых черт() перед любым обратным слэшем и двойными кавычками в шаблоне для i

<AHREF=\\"\S+\">(?<name>\S+)</A>

nstance, в методе GetDirectoryListingRegexForUrl вы должны использовать что-то вроде этого

return "< A href= \\" \S +\\ " > (?\S +)";

Ура!

Ответ 5

Следующий код хорошо работает для меня, когда у меня нет доступа к ftp-серверу:

public static string[] GetFiles(string url)
{
    List<string> files = new List<string>(500);
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
    using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
    {
        using (StreamReader reader = new StreamReader(response.GetResponseStream()))
        {
            string html = reader.ReadToEnd();

            Regex regex = new Regex("<a href=\".*\">(?<name>.*)</a>");
            MatchCollection matches = regex.Matches(html);

            if (matches.Count > 0)
            {
                foreach (Match match in matches)
                {
                    if (match.Success)
                    {
                        string[] matchData = match.Groups[0].ToString().Split('\"');
                        files.Add(matchData[1]);
                    }
                }
            }
        }
    }
    return files.ToArray();
}

Однако, когда у меня есть доступ к ftp-серверу, следующий код работает намного быстрее:

public static string[] getFtpFolderItems(string ftpURL)
{
    FtpWebRequest request = (FtpWebRequest)WebRequest.Create(ftpURL);
    request.Method = WebRequestMethods.Ftp.ListDirectory;

    //You could add Credentials, if needed 
    //request.Credentials = new NetworkCredential("anonymous", "password");

    FtpWebResponse response = (FtpWebResponse)request.GetResponse();

    Stream responseStream = response.GetResponseStream();
    StreamReader reader = new StreamReader(responseStream);

    return reader.ReadToEnd().Split("\r\n".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
}

Ответ 6

Вы не можете, если только указанный вами каталог не содержит список каталогов и не имеет файла по умолчанию (обычно index.htm, index.html или default.html, но всегда настраивается). Только после этого вам будет представлен список каталогов, который обычно будет помечен HTML и требует разбора.

Ответ 7

Вы также можете установить сервер для WebDAV.