You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用C#从指定URL子目录提取.log和.txt格式文件URL

远程URL目录下提取指定后缀文件的实现方法

你原来用的Directory.GetFiles是专门操作本地文件系统的API,完全没法处理HTTP/HTTPS远程URL,所以肯定用不了。要实现远程URL下的文件遍历提取,得根据目标服务器的情况来选方案:

方案一:服务器开启目录列表功能(可直接浏览文件列表)

如果目标服务器允许目录索引(比如Apache、Nginx开启了目录浏览,访问URL会显示文件和子目录的列表页面),可以通过爬取页面+解析HTML的方式实现:

实现步骤

  • 用HttpClient请求目标URL的页面内容
  • 解析HTML提取所有<a>标签的链接
  • 过滤出后缀为.log或.txt的文件链接,将相对路径转为绝对URL
  • 递归处理子目录的链接,重复上述步骤

C#示例代码

需要先安装HtmlAgilityPack NuGet包来解析HTML:

using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Threading.Tasks;
using HtmlAgilityPack;

public class RemoteFileScraper
{
    private static readonly HttpClient _httpClient = new HttpClient();
    private static readonly HashSet<string> _targetExtensions = new HashSet<string> { ".log", ".txt" };
    private static readonly HashSet<string> _visitedUrls = new HashSet<string>(); // 避免重复访问

    public static async Task<List<string>> GetTargetFilesAsync(string baseUrl)
    {
        var result = new List<string>();
        if (!_visitedUrls.Add(baseUrl))
            return result;

        try
        {
            var response = await _httpClient.GetAsync(baseUrl);
            response.EnsureSuccessStatusCode();
            var htmlContent = await response.Content.ReadAsStringAsync();

            var doc = new HtmlDocument();
            doc.LoadHtml(htmlContent);

            foreach (var aNode in doc.DocumentNode.SelectNodes("//a[@href]"))
            {
                var href = aNode.GetAttributeValue("href", string.Empty);
                if (string.IsNullOrEmpty(href) || href.StartsWith("#") || href.StartsWith("?"))
                    continue;

                // 拼接绝对URL
                var absoluteUrl = new Uri(new Uri(baseUrl), href).ToString();

                // 判断是文件还是子目录
                if (absoluteUrl.EndsWith("/"))
                {
                    // 递归处理子目录
                    var subDirFiles = await GetTargetFilesAsync(absoluteUrl);
                    result.AddRange(subDirFiles);
                }
                else
                {
                    // 过滤目标后缀的文件
                    var extension = System.IO.Path.GetExtension(absoluteUrl).ToLower();
                    if (_targetExtensions.Contains(extension))
                    {
                        result.Add(absoluteUrl);
                    }
                }
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine($"访问 {baseUrl} 出错: {ex.Message}");
        }

        return result;
    }
}

// 使用示例
// var files = await RemoteFileScraper.GetTargetFilesAsync("https://example.com/folder1");

方案二:调用服务器提供的文件列表API

如果目标服务器有专门的接口(比如REST API)返回文件结构数据(JSON/XML格式),直接调用API解析是更可靠的方式,不用依赖页面结构的变化:

C#示例代码(假设API返回JSON数组)

using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Threading.Tasks;
using System.Text.Json;

public class FileApiClient
{
    private static readonly HttpClient _httpClient = new HttpClient();
    private static readonly HashSet<string> _targetExtensions = new HashSet<string> { ".log", ".txt" };

    public static async Task<List<string>> GetTargetFilesAsync(string apiUrl)
    {
        var result = new List<string>();
        try
        {
            var response = await _httpClient.GetAsync(apiUrl);
            response.EnsureSuccessStatusCode();
            var jsonContent = await response.Content.ReadAsStringAsync();

            // 假设API返回的是包含文件信息的数组,每个元素有"url"字段
            var files = JsonSerializer.Deserialize<List<FileInfo>>(jsonContent);
            if (files != null)
            {
                foreach (var file in files)
                {
                    var extension = System.IO.Path.GetExtension(file.Url).ToLower();
                    if (_targetExtensions.Contains(extension))
                    {
                        result.Add(file.Url);
                    }
                    // 如果有子目录API,递归调用
                    if (!string.IsNullOrEmpty(file.SubDirectoryApiUrl))
                    {
                        var subDirFiles = await GetTargetFilesAsync(file.SubDirectoryApiUrl);
                        result.AddRange(subDirFiles);
                    }
                }
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine($"调用API出错: {ex.Message}");
        }
        return result;
    }

    // 对应API返回的文件信息结构
    private class FileInfo
    {
        public string Url { get; set; }
        public string SubDirectoryApiUrl { get; set; }
    }
}

// 使用示例
// var files = await FileApiClient.GetTargetFilesAsync("https://example.com/api/files?path=/folder1");

注意事项

  • 方案一依赖服务器的目录列表页面结构,如果页面样式或链接规则变化,代码可能失效
  • 两种方案都需要处理HTTP请求的异常(比如403禁止访问、网络错误等)
  • 不要频繁请求服务器,避免触发反爬机制

内容的提问来源于stack exchange,提问作者Karmesh Duggar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 16:27:35