И вот - придя домой я вспомнил про один интересный класс - 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 {
23 http://bing.ru/,
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-й строке вызовется автоматически, прошу заметить, что я не создавал отдельный обработчик, а заюзал лямбда выражение
Спасибо, пригодилсоь
ОтветитьУдалить