Как скачать страницу сайта или - как скачать сайт

Эта задача появилась в рабочем процессе, я, естесственно, создал вебреквесты, прочитал респонсы и т.п. но вышло около 10 строк, естественно - вынес в функцию, но все же не удобно, а что если нужно файл скачать, или наоборот - аплоадить? для каждого из действий писать по функции - не очень удобно.

И вот - придя домой я вспомнил про один интересный класс - WebClient, странно, и почему сразу его не заюзал, наверное потому, никогда и не юзал.

И так, расположен класс в namespace System.Net, вот пример скачивания сайта:

string str = new WebClient().DownloadString(http://bing.com/);


после выполнения такого кода в строке будет html ответ от сервера, все просто, очень просто :)

ниже приведен пример хендлера (накатал в дороге, по пути на работу), скачивает и выдает html c bing.com, а также асинхронно качает страницы гугла и бинга и кладет их в папку на диске c:\mysiteindex\

Также я описал полезную функцию для смены кодировки у строки, проше смотреть весь код целиком:


    1 <%@ WebHandler Language="C#" Class="Handler" %>
    2 
    3 using System;
    4 using System.Web;
    5 using System.Collections.Generic;
    6 using System.Text;
    7 using System.Net;
    8 
    9 public class Handler : IHttpHandler {
   10 
   11     public void ProcessRequest (HttpContext context)
   12     {
   13         // пример синхронного скачивания сайта 
   14         string str = new WebClient().DownloadString(http://bing.com/);
   15         context.Response.Write(Encode(str, Encoding.Default, Encoding.UTF8));
   16         /////////////////////////////////////
   17 
   18         ///страницы, которые будем скачивать
   19         List<string> pages = new List<string>
   20                 (
   21                     new string[]
   22                         {
   25                         }
   26                 );
   27 
   28         /// ниже асинхронное скачивание
   29         foreach (string page in pages)
   30         {
   31             WebClient wc = new WebClient();
   32 
   33             wc.DownloadStringAsync(new Uri(page)); // маленькое неудобство
   34             wc.BaseAddress = page;
   35 
   36             // эта функция вызовется после скачивания, при этом - пользователь уже получит ответ от хендлера, тем и полезна асинхронность :)
   37             wc.DownloadStringCompleted += (client, data) =>
   38                 {
   39                     // куда сохранять
   40                     string saveTo = @"c:\mysiteindex\" + (client as WebClient).BaseAddress.Replace("/", "_").Replace(":", "!") + ".html";
   41 
   42                     // записываем результат с проверкой кодировки
   43                     if ((client as WebClient).ResponseHeaders.Get("content-type").Contains("utf-8"))
   44                         System.IO.File.WriteAllText(saveTo, Encode(data.Result, Encoding.Default, Encoding.UTF8), Encoding.UTF8);
   45                     else
   46                         System.IO.File.WriteAllText(saveTo, data.Result, Encoding.UTF8);
   47                 };
   48         }
   49     }
   50 
   51     /// <summary>
   52     /// функция меняющая  кодировку строки
   53     /// </summary>
   54     private string Encode(string source, System.Text.Encoding from, System.Text.Encoding to)
   55     {
   56         byte[] encodedsource = from.GetBytes(source);
   57         return to.GetString(encodedsource);
   58     }
   59 
   60     /// <summary>
   61     /// Ерунда какая-то
   62     /// </summary>
   63     public bool IsReusable {
   64         get {
   65             return false;
   66         }
   67     }
   68 
   69 }
на 15-й строке - вывожу результат скачивания бинга
19-я - объявляю список адресов страниц, которые нужно скачать
29-я - бегаю по списку адресов страниц
31-я - создаю веб-клиент
33-я - сообщаю классу - какой адрес выкачивать
34-я - запоминаю в BaseAddress - какой адрес качаю (скорее не для этого нужно юзать, но незапречается, и внутри класса не юзается)
37-я - добавляю обработчик на завершение скачивания
40-я - определяю - куда буду сохранять полученную информацию
43-я - проверяю кодировку и сохраняю так, чтобы сохранились русские символы
по завершении скачивания, функция в 37-й строке вызовется автоматически, прошу заметить, что я не создавал отдельный обработчик, а заюзал лямбда выражение

1 комментарий:

Можете оставить свой комментарий