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

问题描述

我正在尝试从

下载图像

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

使用 WebClient。

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

enter image description here

网址以 .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 直接。.. 我总是遇到同样的错误

enter image description here

有什么想法吗?

解决方法

您的代码很好,但这是特定于服务器的行为。添加一些请求标头可解决此问题。

这是一个使用 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.

下载的图片

enter image description here

,

您的问题与标题有关。但是,让我们从正确的轨道开始,教您使用 DI服务IHttpClientFactory 发出 Http 请求的一种更现代的方法。>

服务

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,*/*;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();

注意:关于如何做到这一点,还有更多变化。然而,至少你没有学习旧的和被破坏的做事方式

,

服务器似乎只为支持压缩的请求提供服务。 WebClient 不支持自动压缩。您可以通过继承您自己的类来启用对压缩的支持,如 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