使用 C# 从 url 下载 .webp 图像

Download .webp image from url with C#

我正在尝试从

下载图片

http://aplweb.soriana.com/foto/fotolib/14/7503003936114/7503003936114-01-01-01.jpg

使用网络客户端。

当我浏览 Chrome 中的图像时,图像就在那里:

url 以 .jpg 结尾,但图像为 .WEBP 格式。

    using (WebClient wb = new WebClient())
    {                  
         wb.DownloadFile("http://aplweb.soriana.com/foto/fotolib//14/7503003936114/7503003936114-01-01-01.jpg", "image.jpg");
    }

我已经尝试 .DownloadData()、asyng 方法、HttpClient、WebRequest 直接。.. 但我总是遇到同样的错误。

有什么想法吗?

您的代码没有问题,但这是 server-specific 行为。添加一些请求 headers 解决了这个问题。

这是一个使用 HttpClient

的示例
class Program
{
    private static readonly HttpClient client = new HttpClient(new HttpClientHandler() { AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate });

    static async Task Main(string[] args)
    {
        client.DefaultRequestHeaders.Accept.ParseAdd("text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
        client.DefaultRequestHeaders.AcceptEncoding.ParseAdd("gzip, deflate");
        try
        {
            Console.WriteLine("Downloading...");
            byte[] data = await client.GetByteArrayAsync("http://aplweb.soriana.com/foto/fotolib//14/7503003936114/7503003936114-01-01-01.jpg");
            Console.WriteLine("Saving...");
            File.WriteAllBytes("image.jpg", data);
            Console.WriteLine("OK.");
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
    }
}

控制台输出

Downloading...
Saving...
OK.

已下载图片

服务器似乎只处理支持压缩的请求。 WebClient 不支持自动压缩。您可以通过继承自己的 class 来启用对压缩的支持,如 this answer.

中所述
class MyWebClient : WebClient
{
    protected override WebRequest GetWebRequest(Uri address)
    {
        HttpWebRequest request = base.GetWebRequest(address) as HttpWebRequest;
        request.AutomaticDecompression =  DecompressionMethods.Deflate | DecompressionMethods.GZip;
        return request;
    }
}

然后使用 MyWebClient 而不是 WebClient

您的问题与 headers 有关。但是,让我们让您走上正轨,并教您使用 DIServices 和 [= 发出 Http 请求的更现代的方法之一13=].

服务

public class MyFunkyService
{
   private readonly IHttpClientFactory _clientFactory;

   public MyFunkyService(IHttpClientFactory clientFactory)
    => _clientFactory = clientFactory;

   public async Task<byte[]> GetSomeFunkyThingAsync()
   {
      using var client = _clientFactory.CreateClient();
      using var request = new HttpRequestMessage(HttpMethod.Get, "http://aplweb.soriana.com/foto/fotolib//14/7503003936114/7503003936114-01-01-01.jpg");

      request.Headers.Accept.ParseAdd("text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
      request.Headers.AcceptEncoding.ParseAdd("gzip, deflate");

      using var response = await client
         .SendAsync(request)
         .ConfigureAwait(false);

      response.EnsureSuccessStatusCode();

      return await response
         .Content
         .ReadAsByteArrayAsync()
         .ConfigureAwait(false);

   }
}

设置

var provider = new ServiceCollection()
   .AddHttpClient()
   .AddSingleton<MyFunkyService>()
   .BuildServiceProvider();

用法

// this would be injected 
var myClient = provider.GetRequiredService<MyFunkyService>();

var result = await myClient.GetSomeFunkyThingAsync();

注意:关于如何做到这一点,还有更多变体。但是至少你没有学习旧的和失败的做事方式