Пишем простой парсер файлов (для начинающих)

от автора

В этой статье я хотел бы рассказать как написать простой парсер на примере сайтов aimp.ru и geekbrains.ru. Статья предназначена строго для тех, кто уже имеет базовые знания о языке программирования C# и уже написал свой первый «Hello world».

Мне всегда нравился аудиоплеер Aimp (нет, это не реклама), но встроенных скинов у него слишком мало, а заходить на сайт, смотреть скины, скачивать и пробовать как они будут смотреться на деле не было никакого желания. Поэтому я решил написать парсер скинов с данного сайта. Немного посмотрев сайт, я заметил, что скины там хранятся последовательно с присвоенным id. Т.к. до недавнего времени я знал только 1С и немного командную строку, то недолго думая я решил написать его в командной строке. Но при тестировании обнаружил, что если скачивать большое количество файлов, то во-первых часть может просто не скачаться, а во-вторых может произойти переполнение оперативной памяти. В итоге я тогда бросил эту затею.

Не так давно начав изучать C# я решил вернуться к этой идее, дабы попрактиковаться немного. Что из этого получилось читайте под катом.

Для разработки нам понадобится только среда разработки, я использовал Visual Studio, вы можете использовать любую другую на ваш вкус.

Я не буду углубляться в базовые понятия C#, для этого написано множество различных книг и отснято бесчисленное количество роликов.

Для начала запустим Visual Studio и создадим консольное приложение (т.к. мне лень делать формы нам не нужен интерфейс). Среда разработки нам сама подготовит шаблон проекта. У нас получится что-то вроде этого:

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;  namespace ConsoleApplication2 {     class Program     {         static void Main(string[] args)         {         }     } }  

Удаляем директивы которыми мы пользоваться сейчас не будем:

using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; 

И добавляем те директивы, которыми будем пользоваться:

using System.Diagnostics;   // Нужна, чтобы запускать внешние процессы using System.Net;           // Нужна, чтобы работать с Web using System.Threading;     // Нужна, чтобы скоротать время 

После чего в методе Main объявляем переменную:

WebClient wc = new WebClient(); // Она нужна непосредственно для работы с Web 

Парсим Aimp скины

Далее мы пишем саму функцию:

static string DownloadSkinsForAimp(WebClient wc)         {             Console.WriteLine("Downloading began");             try             {                 for (int i = 0; i <= 5; i++)                 {                     string id = "79" + i;                     string name = GetNameOfSkin(wc, id);                      // Путь, откуда мы будем скачивать                     string path = "aimp.ru/index.php?do=download&sub=catalog&id=" + id;                                                             try                     {                         // Запускаем нужный нам браузер и передаем ему в качестве аргумента путь скачивания                         Process.Start("chrome.exe", path);                          Console.WriteLine("Download " + name + " is succesfull!");                          // Ждем 5 секунд, чтобы вкладки успевали закрываться, иначе может быть переполнение памяти                         Thread.Sleep(5000);                     }                     catch                     {                         Console.WriteLine("Download" + name + "failed");                     }                 }             }             catch             {                 return "\nSomething went is wrong";             }             return "\nDownloading complete";                      } 

Все скины скачиваются в директорию, заданную в настройках браузера. Конструкции try/catch нам нужны для того, чтобы программа не «вываливалась» из-за ошибок. Хотя можно было обойтись и без них.

Вы могли заметить функцию GetNameOfSkin. Она нужна для того, чтобы получить название скина, который мы скачиваем. Можно обойтись и без неё, она нужна только для красоты, но раз мы только учимся, то напишем и её:

 static string GetNameOfSkin(WebClient wc, string id)         {             // Получаем строку с html разметкой             string html = wc.DownloadString("http://www.aimp.ru/index.php?do=catalog&rec_id=" + id);             // Находим в ней первое упоминание нужного нам id и удаляем ненужную левую часть             // Название скина начинается через 5 символов после этого id             string rightPartOfHtml = html.Substring(html.IndexOf(id) + 5);             // Находим конец названия и удаляем оставшуюся правую часть             string name = rightPartOfHtml.Substring(0, rightPartOfHtml.IndexOf("<")).Replace(" ", "_");             // В итоге нам возвращается только само название скина             return name;         } 

Далее в методе Main нужно вызвать скачивание на выполнение:

Console.WriteLine(DownloadSkinsForAimp(wc)); // На консоль нужно выводить потому, что                                                                               // метод возвращает нам строку с результатом выполнения 

Парсим сертификаты Geekbrains

Сертификаты на сайте хранятся в открытом виде, и открыв их через сайт, как скины aimp мы сможем их скачать только вручную нажав кнопку скачать. Но это не дело, мы же программисты.

Тут нам на помощь приходит класс WebClient, а именно его метод DownloadFile. Ему мы просто передаем путь для скачивания и путь для сохранения и он все делает за нас. Звучит легко, попробуем сделать:

static string DownloadCertificates(WebClient wc)         {             // Нужна для того, чтобы определить имя текущего пользователя             string currentUser = Environment.UserName;              Console.WriteLine("Downloading began");              try             {                 for (int i = 0; i <= 5; i++)                 {                     try                     {                         // Все сертификаты на данном сайте хранятся в формате '.pdf'                         wc.DownloadFile("https://geekbrains.ru//certificates//7075" + i + ".pdf", "c:\\users\\" + currentUser + "\\downloads\\7075" + i + ".pdf");                          Console.WriteLine("Download certificate №7075" + i + " is succesfull");                     }                     catch                     {                         Console.WriteLine("Download certificate №7075" + i + " is failed");                     }                 }             }             catch             {                 return "\nSomething went is wrong";             }             return "\nDownloading certificates are complite!";         } 

И после чего точно также вызываем эту функцию из метода Main.

Вообще обе эти функции ещё есть куда дорабатывать, но я думаю для ознакомления и самых базовых функций парсинга они вполне подойдут. Кому лень все это собирать в один проект — вот ссылка на GitHub.

Спасибо за внимание и надеюсь, кому-нибудь это поможет.

P.S.: Сертификаты с geekbrains можно скачать и изменить имя и фамилию владельца на свою полюбоваться на них.

P.P.S.: Все скины, скачанные с сайта Aimp, хранятся в формате ‘.zip’ и при желании функцию можно доработать, чтобы она сама их разархивировала. Также можно добавить, чтобы они сразу переносились в папку со скинами Aimp.

P.P.P.S.: Статья является исключительно познавательной и не несет рекламный характер.

ссылка на оригинал статьи https://habrahabr.ru/post/282119/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *