2008-09-23 3 views

ответ

27

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

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

Мой выбор - использовать регулярные выражения. Это позволяет быстро разборе и настройке. Вы можете получить определенный шаблон регулярных выражений для каждого сайта, и таким образом у вас будет очень модульный подход. Используйте внешний источник для сопоставления 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(); 
     } 
    } 
} 
8

Базовое понимание:

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

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

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

Каталог просмотра:

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

Быстрого пример HTML Agility обновления:

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-страницах страницы. Это не даст вам полную информацию о том, какие файлы на самом деле находятся на веб-сервере.

0

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

0

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

2

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

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

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

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

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

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

возвращение «< A HREF = \\" \ S + \\ "> (? \ S +)";

Cheers!

+0

Большое спасибо. Это сэкономило время. – 2013-10-16 09:39:15

4

я просто модифицирована выше, и нашел, что это лучший

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(); 
     } 
    } 
} 
1

Следующий код работает хорошо для меня, когда у меня нет доступа к 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); 
} 
Смежные вопросы