使用 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 有关。但是,让我们让您走上正轨,并教您使用 DI、Services 和 [= 发出 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();
注意:关于如何做到这一点,还有更多变体。但是至少你没有学习旧的和失败的做事方式
我正在尝试从
下载图片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 有关。但是,让我们让您走上正轨,并教您使用 DI、Services 和 [= 发出 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();
注意:关于如何做到这一点,还有更多变体。但是至少你没有学习旧的和失败的做事方式