C#HttpWebRequest命令获取目录列表

我需要一个简短的代码片段来从HTTP服务器获取目录列表。

谢谢

代码之前的一些重要注意事项:

  1. 必须将HTTP Server配置为允许列出所需目录的目录;
  2. 因为目录列表是普通的HTML页面,所以没有标准来定义目录列表的格式;
  3. 由于考虑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 "(?.*)"; } 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(); } } } 

基本了解:

目录列表只是Web服务器生成的HTML页面。 每个Web服务器都以自己的方式生成这些HTML页面,因为Web服务器没有标准的方法来列出这些目录。

获取目录列表的最佳方法是简单地对您希望目录列表的URL执行HTTP请求,并尝试解析并从返回给您的HTML中提取所有链接。

要解析HTML链接,请尝试使用HTML Agility Pack 。

目录浏览:

您要列出目录的Web服务器必须启用目录浏览才能在其目录中获取文件的HTML表示forms。 因此,只有HTTP服务器希望您能够获取目录列表。

HTML Agility Pack的一个简单示例:

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

清洁替代品:

如果在您的情况下可行,则更简洁的方法是使用目标列表的目标协议,如文件传输协议(FTP),SFTP(FTP之类的SSH)或FTPS(基于SSL的FTP)。

如果未打开目录浏览,该怎么办:

如果Web服务器没有打开目录浏览,则没有简单的方法来获取目录列表。

在这种情况下,您可以做的最好的事情是从给定的URL开始,遵循同一页面上的所有HTML链接,并尝试根据这些HTML页面上的资源的相对路径自己构建目录的虚拟列表。 这不会为您提供Web服务器上实际存在的文件的完整列表。

我刚才修改过,发现这个最好

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

谢谢你的精彩post。 对我来说,下面的模式效果更好。

 (?\S+) 

我还在http://regexhero.net/tester上测试了它。

要在你的C#代码中使用它,你必须在任何反斜杠之前添加更多的反斜杠(),并在i的模式中添加双引号

(?\S+)

nstance,在GetDirectoryListingRegexForUrl方法中你应该使用这样的东西

返回“(?\ S +)”;

干杯!

当我无法访问ftp服务器时,以下代码适用于我:

 public static string[] GetFiles(string url) { List files = new List(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("(?.*)"); 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设置服务器。