2008-09-23 36 views

Trả lời

27

Một vài lưu ý quan trọng trước khi mã:

  1. Các HTTP Server phải được cấu hình để cho phép các thư mục danh sách cho các thư mục bạn muốn;
  2. Bởi vì danh sách thư mục là các trang HTML bình thường nên không có tiêu chuẩn xác định định dạng danh sách thư mục;
  3. Do xem xét bạn đang ở trong vùng đất nơi bạn phải đặt mã cụ thể cho từng máy chủ.

Lựa chọn của tôi là sử dụng cụm từ thông dụng. Điều này cho phép phân tích và tùy chỉnh nhanh chóng. Bạn có thể nhận được mẫu biểu thức chính quy cụ thể trên mỗi trang web và theo cách đó bạn có cách tiếp cận rất mô-đun. Sử dụng nguồn bên ngoài để ánh xạ URL tới các mẫu biểu thức chính quy nếu bạn có kế hoạch nâng cao mô-đun phân tích cú pháp với các trang web mới hỗ trợ mà không thay đổi mã nguồn.

Ví dụ để in danh sách thư mục từ 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

hiểu biết cơ bản:

Danh sách thư mục chỉ là các trang HTML được tạo ra bởi một máy chủ web. Mỗi máy chủ web tạo các trang HTML này theo cách riêng vì không có cách nào tiêu chuẩn cho máy chủ web liệt kê các thư mục này.

Cách tốt nhất để có danh sách thư mục là chỉ cần thực hiện yêu cầu HTTP đến URL bạn muốn danh sách thư mục và cố gắng phân tích cú pháp và trích xuất tất cả các liên kết từ HTML được trả lại cho bạn.

Để phân tích cú pháp các liên kết HTML, hãy thử sử dụng HTML Agility Pack.

Directory Browsing:

Các máy chủ web mà bạn muốn liệt kê các thư mục từ phải có việc duyệt thư mục bật để có được đại diện HTML này của các tập tin trong thư mục của nó. Vì vậy, bạn chỉ có thể nhận được danh sách thư mục nếu máy chủ HTTP muốn bạn có thể.

Một ví dụ nhanh chóng của các Agility Pack HTML:

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

Cleaner thay thế:

Nếu có thể trong tình huống của bạn, một phương pháp sạch hơn là sử dụng một giao thức dự định cho thư mục danh sách, như Giao thức truyền tệp (FTP), SFTP (FTP như qua SSH) hoặc FTPS (FTP qua SSL).

gì nếu việc duyệt thư mục không được bật:

Nếu máy chủ web không có việc duyệt thư mục bật, sau đó không có cách nào dễ dàng để có được danh sách thư mục.

Điều tốt nhất bạn có thể làm trong trường hợp này là bắt đầu tại một URL nhất định, theo tất cả các liên kết HTML trên cùng một trang và tự mình xây dựng danh sách thư mục ảo dựa trên đường dẫn tương đối của tài nguyên trên các HTML này các trang. Điều này sẽ không cung cấp cho bạn một danh sách đầy đủ của những tập tin thực sự trên máy chủ web mặc dù.

0

Bạn không thể, trừ khi thư mục cụ thể bạn muốn có danh sách thư mục được bật và không có tệp mặc định (thường là index.htm, index.html hoặc default.html nhưng luôn có thể định cấu hình). Chỉ sau đó bạn sẽ được trình bày với một danh sách thư mục, thường sẽ được đánh dấu bằng HTML và yêu cầu phân tích cú pháp.

0

Hoặc bạn có thể thiết lập máy chủ cho WebDAV.

2

Cảm ơn bài đăng tuyệt vời. đối với tôi, mẫu bên dưới hoạt động tốt hơn.

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

Tôi cũng đã thử nghiệm tại http://regexhero.net/tester.

để sử dụng nó trong mã C#, bạn phải thêm dấu xồ nguợc() trước khi bất kỳ dấu chéo ngược và dấu ngoặc kép trong mô hình cho i

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

nstance, trong phương pháp GetDirectoryListingRegexForUrl bạn nên sử dụng một cái gì đó như thế này

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

Chúc mừng!

+0

Cảm ơn rất nhiều. Nó tiết kiệm thời gian. –

4

tôi chỉ cần sửa đổi trên và thấy điều này tốt nhất

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

Các mã sau hoạt động tốt đối với tôi khi tôi không có quyền truy cập đến máy chủ 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(); 
} 

Tuy nhiên, khi Tôi có quyền truy cập vào máy chủ ftp, mã sau đây hoạt động nhanh hơn nhiều:

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); 
} 
Các vấn đề liên quan