5

I'm working on batch downloader but some URLs are not sending data correctly.

For example, this page: http://i.imgbox.com/absMQK6A.png

In any internet browser, this page shows an image, but in my program, downloads strange data. I think this URL is fake or protected (I don't know HTML well.)

BTW, in IE, I can download that image normally with right click and save as image. so I want to emulate that behavior in my program.

How can I do this?

Below is part of my program's code.

HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(DownloadAddress);
if (Proxy != null)
{
    request.Proxy = Proxy;
}
if (!string.IsNullOrWhiteSpace(UserAgent))
{
    request.UserAgent = UserAgent;
}

HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Stream downloadHttpStream = response.GetResponseStream();
int read = downloadHttpStream.Read(buffer, 0, buffer.Length);
// output codes

UserAgent is string that has informations of browser. such as IE, Firefox etc.

Thanks.

Nikola Sivkov
  • 2,812
  • 3
  • 37
  • 63

4 Answers4

4

If you look at the first few bytes of the data you get back with your code, you can see that it starts with 1F 8B 08. This indicates that the data is gzip'd data (gzip encoding is a common thing on the web). You can include the AutomaticDecompression property to make the .Net code automatically decompress this data and get your valid PNG (the bytes start with 89 50 4E 47):

var request = (HttpWebRequest)HttpWebRequest.Create(DownloadAddress);
request.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
Tim S.
  • 55,448
  • 7
  • 96
  • 122
0

I'm not sure if that's what you wanted, although give it a try

Image img;
var request = WebRequest.Create(DownloadAddress);

using (var response = request.GetResponse())
using (var stream = response.GetResponseStream())
{
    img = Bitmap.FromStream(stream);
}

I don't know if you want to actually load it or just download it, but this way you'll be able to easily check whether it's doable

img.Save(somePath);
Tarec
  • 3,268
  • 4
  • 30
  • 47
  • Thank you for answer. But throw an `ArgumentException` at `img = Bitmap.FromStream(stream);`. –  Apr 24 '14 at 15:52
0

You don't get an image because it's in Base64 , with this online converter you can paste the response from the site and convert it to image just for the test.

Also, the browsers have built in support for Base64 encoded images. They are often used to embed small icons inline to avoid additional http requests.

As how to solve your problem :

  1. try to download the image as usual
  2. check if it worked ( try catch for exceptions and check for size )
  3. if there are exceptions try to convert it from base64 like this
  4. if that doesn't work show an error or save the image path somewhere for inspection later on

In addition you can also add support for WebP images as they are quietly becoming more and more popular. There is a WebP library for .net on codeplex

Community
  • 1
  • 1
Nikola Sivkov
  • 2,812
  • 3
  • 37
  • 63
  • Thank you for answer. That was the point! but now have problem to convert bytes to C# string. `b64 = Encoding.ASCII.GetString(pageData.ToArray());` result is not valid Base64. –  Apr 24 '14 at 16:09
  • @JIH Please refer to Tim's code for a better code solution :) but you should still have different checks for different stuff :) – Nikola Sivkov Apr 24 '14 at 16:15
0

Well you can always download the image using

var webClient = new WebClient();
byte[] buffer = webClient.DownloadData("http://i.imgbox.com/absMQK6A.png");
Sílvio N.
  • 361
  • 2
  • 13