Мне нужен короткий фрагмент кода, чтобы получить список каталогов с HTTP-сервера.
Спасибо
Мне нужен короткий фрагмент кода, чтобы получить список каталогов с HTTP-сервера.
Спасибо
Несколько важных соображений перед кодом:
Мой выбор - использовать регулярные выражения. Это позволяет быстро разборе и настройке. Вы можете получить определенный шаблон регулярных выражений для каждого сайта, и таким образом у вас будет очень модульный подход. Используйте внешний источник для сопоставления 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();
}
}
}
Основное понимание:
Списки каталогов - это только 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-страницах, Это не даст вам полную информацию о том, какие файлы на самом деле находятся на веб-сервере.
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();
}
}
}
Спасибо за отличный пост. для меня картина ниже работала лучше.
<AHREF=\\"\S+\">(?<name>\S+)</A>
Я также тестировал его на http://regexhero.net/tester.
чтобы использовать его в коде С#, вы должны добавить больше обратных косых черт() перед любым обратным слэшем и двойными кавычками в шаблоне для i
<AHREF=\\"\S+\">(?<name>\S+)</A>
nstance, в методе GetDirectoryListingRegexForUrl вы должны использовать что-то вроде этого
return "< A href= \\" \S +\\ " > (?\S +)";
Ура!
Следующий код хорошо работает для меня, когда у меня нет доступа к 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);
}
Вы не можете, если только указанный вами каталог не содержит список каталогов и не имеет файла по умолчанию (обычно index.htm, index.html или default.html, но всегда настраивается). Только после этого вам будет представлен список каталогов, который обычно будет помечен HTML и требует разбора.
Вы также можете установить сервер для WebDAV.