C#HttpWebRequest命令获取目录列表

时间:2020-03-06 14:38:03  来源:igfitidea点击:

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

谢谢

解决方案

基本了解:

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

获取目录列表的最佳方法是,简单地对我们想要目录列表的URL进行HTTP请求,并尝试解析并提取返回给HTML中的所有链接。

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

目录浏览:

我们要从中列出目录的Web服务器必须打开目录浏览功能,以获取目录中文件的HTML表示形式。因此,只有在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(类似于SSH的FTP)或者FTPS(基于SSL的FTP)。

如果没有打开目录浏览怎么办:

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

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

除非我们要的特定目录启用了目录列表,并且没有默认文件(通常为index.htm,index.html或者default.html,但始终可配置),否则我们将不能这样做。只有这样,我们才能看到目录列表,该目录通常会用HTML标记并需要解析。

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

  • 必须将HTTP Server配置为允许列出所需目录的目录。
  • 因为目录列表是普通的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();
        }
    }
}

我们也可以为WebDAV设置服务器。