2 место Снипеты от А до Я

Discussion in 'Первый конкурс статей' started by 7make, Apr 22, 2014.

  1. 7make

    7make Moderator

    Joined:
    Jun 25, 2011
    Messages:
    1,483
    Likes Received:
    1,158
    Intro

    Эта статья о снипетах на языке С# (Си шарп). Статья ориентирована на тех пользователей, которые слышали о его поддержке в ZennoPoster, но их пугало слово программирование и им казалось что это сложно. В этой статье не будет акцента на углубление в изучении языка C#. В этой статье акцент на тех базовых возможностях языка которые собственно и достаточно знать для решения большинства задач с которыми Вы сталкиваетесь при каждом новом проекте для ZennoPoster. Только в первом блоке мы затронем немного теории и понятий которые нельзя не затронуть. Только самое используемое из личного опыта.

    Типы данных

    Язык C# - язык со строгой типизацией. Любые данные имеют некий тип, и этот тип нужно указывать.
    На схеме мы видим множество типов, но только с несколькими из них Вы будете сталкиваться в 90% случаев при написании проектов.

    [​IMG]
    Синтаксис оформления переменных:

    тип имя = значение;

    Основные типы которых будет достаточно знать.

    Code (csharp):
    1.  
    2. //Логический тип. Принимает true или false
    3. bool flag = false;
    4.  
    5. //Тип char. Символы
    6. char symbol = 'Z';
    7.  
    8. //Тип string. Строки/Текст
    9. string str = "Zenno";
    10.  
    11. //Тип int. Число от -2147483648 до 2147483647
    12. int x = 0;
    13.  
    14. //Тип var. Универсальный /Динамический тип. Может включать любой тип.
    15. var dyn = SomeType;
    16.  
    Тип string - имеет свойство Length которое вернет число знаков в строке.

    Code (csharp):
    1.  
    2. string str = "некоторая строка";
    3. //В переменной strLenght будет число знаков  строке
    4. int strLenght = str.Length;
    5.  
    Массивы

    Массивы - коллекция (данных)переменных одного типа с общим именем, и доступом к ним по их числовому индексу. Массивы бывают одномерные, многомерные и ступенчатые. Достаточно знать одномерных массивов.


    Синтаксис оформления одномерных массивов:

    тип[] имя;
    тип[] имя = new тип[кол-во элементов];
    тип[] имя = new тип [] {элемент0, элемент1, элемент2}

    В первом случае у нас массив с отложенной инициализацией.
    Достаточно знать первую конструкцию.


    Code (csharp):
    1.  
    2. // Объявляем массив типа int
    3. int[] myArr;
    4.  
    5. // Инициализируем каждый элемент массива вручную
    6. myArr[0] = 8;
    7. myArr[1] = 6;
    8. myArr[2] = 2;
    9. myArr[3] = -1;
    10. myArr[4] = -13;
    11.  


    Списки

    Синтаксис объявления списков

    List<тип> имя = new List<тип>();
    Code (csharp):
    1.  
    2. //Список myList с элементами типа string
    3.  List<string> myList= new List<string>();
    4.  
    5. //Добавим в конец списка элемент
    6. myList.Add("Строка1");
    7.  
    8. //Кол-во строк в списке
    9. int listSize = myList.Count;
    10.  
    Условные операторы

    Оператор if (если)

    Синтаксис:


    if (условие)
    {
    действия;
    }
    else
    {

    действия;
    }


    Code (csharp):
    1.  
    2. //Объявим переменные и установим им значения
    3. int x =1;
    4. int y= 5;
    5.  
    6. //Если x меньше чем y
    7. if(x<y)
    8. {
    9. //Увеличим значение в переменной х на 1
    10. x = x+1;
    11. }
    12. //Иначе
    13. else
    14. {
    15. //Уменьшим значение в переменной х на 1
    16. x = x-1;
    17. }
    18.  
    else - необязательный оператор.

    Циклы for, while и foreach

    Цикл for (счетчик)

    Синтаксис:

    for (начальное значение; условие; шаг)
    {
    //действия
    }

    Code (csharp):
    1.  
    2. //обьявим массив типа string который содержит дни недели
    3. string[] days = new string [] {"Понедельник","Вторник", "Среда", "Четверг", "Пятница", "Суббота", "Воскресенье"};
    4.  
    5. //Переберм все элементы массива
    6. for(int =0; i<days.Length; i++)
    7. {
    8. //если это Среда  
    9. if(days[i]=="Среда")
    10. {
    11. //вернем индекс этого элемента
    12. return i;
    13. }
    14. }
    15.  
    Цикл while

    while
    (true)
    {
    //Действия
    }


    Как и for можно использовать как счетчик.

    Цикл foreach

    foreach (тип имя_переменной_цикла in коллекция)
    {
    //действия;
    }

    Счетчик без условия. Когда нужно перебрать все элементы некой коллекции без необходимости получения индекса элемента.


    Для понимания дальнейшей практической части к которой мы перейдем после этого теоретического блока, стоит обозначить такие понятия как Класс и Метод.

    Класс - структура, позволяющая нам описать некий обьект.
    Включает в себя методы и свойства для взаимодействия с нашим обьектом и придает ему физическую сущность.

    Метод(Функция) - "Черный ящик" выполняющий некие действия над обьектом. Главной особенностью которого является многократное его использование. Все методы принадлежат классам. Передаем в метод аргументы, он выполняет на ними действия и возвращает нам результат. Но методы могут и не принимать аргументов, такие методы называются статическими.

    Когда мы создавали список выше, мы создавали обьект принадлежащий к классу List со свойством Count, которое и придавало ему физическу сущность - размерность.

    Code (csharp):
    1.  
    2. //myList - обьект типа string (строка) принадлежащий к классу List
    3.  List<string> myList= new List<string>();
    4.  
    5. //Add() - метод добавляющий к обьекту строку
    6. myList.Add("Строка1");
    7.  
    8. //Count - свойство обьекта. Его размерность.
    9. int listSize = myList.Count;
    10.  
    Теперь перейдем от нудной но необходимой теории к практической части :-)
    Где собственно и будет практическое применение тех базовых, но достаточных знаний для решения повседневных задач при написании проектов для ZennoPoster.



     
  2. 7make

    7make Moderator

    Joined:
    Jun 25, 2011
    Messages:
    1,483
    Likes Received:
    1,158
    Тип string - работа со строками

    String.Format - метод (String, Object, Object)
    Составная строка в некотором формате.
    [​IMG] [​IMG] [​IMG]

    String.Split - метод (Char[])

    Разбиваем строку на массив по разделителю
    [​IMG]

    String.Trim - метод
    Удалить пробелы в начале и конце строки

    Code (csharp):
    1. string str = " Some string ";
    2. str = str.Trim();

    String.Replace - метод (String, String)
    Заменить часть строки

    Code (csharp):
    1. string str = "Some string";
    2. //Replace(старое значение, новое значение);
    3. str = str.Replace("Some","My Some");
    String.ToLower - метод

    String.ToUpper - метод

    Перевод строки в нижний и верхний регистр

    Code (csharp):
    1. string str = "text";
    2.  
    3. //ToLower -  в нижний регистр
    4. str = str.ToLower();
    5.  
    6. //ToUpper - в верхний
    7. str = str.ToUpper();
    8.  




     
    Last edited: Apr 22, 2014
  3. 7make

    7make Moderator

    Joined:
    Jun 25, 2011
    Messages:
    1,483
    Likes Received:
    1,158
    Массивы на примере одной капчи
    В качестве примера решил привести практическую реализацию распознавания одной капчи.
    Основа всего алгоритма распознавания полностью завязана на возможностях одномерных массивов.
    Этот пример может служить базой при написании распознавалок для подобного вида капч.
    Есть сайт http://radiostationawards.ru На нем такая капча.

    [​IMG]
    Смотря на эту капчу можно увидеть массив. Массив состоящий из 7 элементов = 7 картинок.
    Помнить что нумерация в массивах идет от нуля. Первый элемент массива имеет индекс = 0!

    Когда в Зенно вы выбираете капчу(обьект картинка) за это отвечает метод DrawToBitmap
    который входит в библиотеку классов ZennoLab.CommandCenter. Метод передает эту картинку модулю распознавания, который передает ее уже на сервис распознавания в виде картинки.
    Мы воспользуемся этим методом для своих целей. Целей идентификации картинки.

    Синтаксис метода:

    Code (csharp):
    1.  
    2. //Метод вернет base64 представление нашей картинки в виде строки
    3. public string DrawToBitmap(
    4.    bool isImage
    5. )
    6.  
    Вот так выглядит base64 строка одной картинки из этой капчи. Такую строку вернет нам метод DrawToBitmap.
    Как видим, длина такой строки имеет неудобный вид для работы.
    Воспользуемся Снипетом получения MD5 для строки

    Code (csharp):
    1.  
    2. string input = "base64 строка";
    3.  
    4. // Создаем объект этого класса.
    5. System.Security.Cryptography.MD5 md5Hasher = System.Security.Cryptography.MD5.Create();
    6. // Преобразуем входную строку в массив байт и вычисляем хэш
    7. byte[] data = md5Hasher.ComputeHash(Encoding.Default.GetBytes(input));
    8. // Создаем новый Stringbuilder (Изменяемую строку) для набора байт
    9. StringBuilder md5hash = new StringBuilder();
    10. // Преобразуем каждый байт хэша в шестнадцатеричную строку
    11. for (int i = 0; i < data.Length; i++)
    12. {
    13.     //преобразуем элемент в шестнадцатиричную строку длиной в два символа
    14.     md5hash.Append(data[i].ToString("x2"));
    15. }
    16. //Возвращаем MD5 хеш для строки
    17. return md5hash.ToString();
    18.  
    В результате получим md5 хеш нашей строки.
    Шаг #1 - Создание базы

    Алгоритм действий


    [​IMG]



    После этого нам нужно сохранить в базу текст вопроса и соответствующий хеш.
    Для этого на форму для ручного ввода капчи выведем весь блок капчи с текстом вопроса.
    В качестве ответа вбиваем индекс картинки которую просят выбрать.(Нумерация от нуля!!)
    [​IMG]

    Парсим сам текст картинки которую просят найти.
    Передаем индекс в следующий код.
    Для работы кода нужно добавить using:
    using System.Security.Cryptography;

    Code (csharp):
    1. //Индекс нужной картинки
    2. int index  = Convert.ToInt32(project.Variables["index"].Value);
    3.  
    4. //Массив хешей картинок на странице
    5. string[] md5source = new string[7];
    6.  
    7. //Результат. Будет содержать нужный хеш по индексу
    8. string md5 = String.Empty;
    9.  
    10. //Заполняем массив md5source
    11. for(int i=0; i<md5source.Length; i++)
    12. {
    13.     //Пауза 2с
    14.     System.Threading.Thread.Sleep(2000);
    15.  
    16.     //Находим капчи
    17.     Tab tab = instance.ActiveTab;
    18.     Document doc = tab.MainDocument;
    19.     HtmlElement he = doc.FindElementByAttribute("img", "src", "http://radiostationawards.ru/image.php\\?show=.*", "regexp", i);
    20.  
    21.     //Получаем BASE64 представление каптчи. Стат.метод DrawToBitmap(); возвращает тип string
    22.     string base64 = he.DrawToBitmap(true);
    23.  
    24.     //Получаем md5 от строки base64
    25.     MD5 md5Hasher = MD5.Create();
    26.     byte[] data = md5Hasher.ComputeHash(Encoding.Default.GetBytes(base64));
    27.     StringBuilder md5hash = new StringBuilder();
    28.     for (int j=0; j < data.Length; j++)
    29.     {
    30.         md5hash.Append(data[j].ToString("x2"));
    31.     }
    32.     //Заполняем массив md5 хешами каптч
    33.     md5source[i] = md5hash.ToString();
    34. }
    35.  
    36. //Хеш нужной картинки каптчи по ее индексу
    37. md5 = md5source[index].ToString();
    38.  
    39. //Вернем результат
    40. return md5;
    41.  
    После этого у нас в переменной {-Variable.text-} будет текст вопроса, а в переменной {-Variable.md5-} буде md5 хеш соответствующей картинки.
    Сохраняем все это в список в формате text;md5
    Запустим проект в 5 потоков. Вбиваем индексы нужных нам картинок.Через 30-60 минут получим базу в таком виде

    [​IMG]
     
    Last edited: Apr 25, 2014
    Osminogus, Roman*, List and 11 others like this.
  4. 7make

    7make Moderator

    Joined:
    Jun 25, 2011
    Messages:
    1,483
    Likes Received:
    1,158
    Шаг #2 - Использование базы

    Создаем рабочий проект.
    Подключаем базу как список.
    Используем следующий снипет.

    Code (csharp):
    1.  
    2. //База признаков text;md5
    3. var baselist = project.Lists["base"];
    4.  
    5. //Текст на странице
    6. string text  = project.Variables["text"].Value;
    7.  
    8. //Массив хешей картинок на странице
    9. string[] md5source = new string[7];
    10.  
    11. //Будет содержать md5 найденный из базы признаков
    12. string  md5 = String.Empty;
    13.  
    14. //Будет содержать найденный индекс нужной нам капчи
    15. string index = String.Empty;
    16.  
    17. //Заполняем массив md5source
    18. for(int i=0; i<md5source.Length; i++)
    19. {
    20.     //Находим капчи
    21.     Tab tab = instance.ActiveTab;
    22.     Document doc = tab.MainDocument;
    23.     HtmlElement he = doc.FindElementByAttribute("img", "src", "http://radiostationawards.ru/image.php\\?show=.*", "regexp", i);
    24.  
    25.     //Получаем BASE64 представление каптчи
    26.     string base64 = he.DrawToBitmap(true);
    27.  
    28.     //Получаем md5 от строки base64
    29.     MD5 md5Hasher = MD5.Create();
    30.     byte[] data = md5Hasher.ComputeHash(Encoding.Default.GetBytes(base64));
    31.     StringBuilder md5hash = new StringBuilder();
    32.     for (int j=0; j < data.Length; j++)
    33.     {
    34.         md5hash.Append(data[j].ToString("x2"));
    35.     }
    36.     //Заполняем массив md5 хешами капч
    37.     md5source[i] = md5hash.ToString();
    38. }
    39.  
    40. //Перебираем все строки из базы признаков
    41. foreach(string str in baselist)
    42. {
    43.     //Если строка содержит text
    44.     if(str.Contains(text))
    45.     {
    46.         //Отделим text от md5 и поместим в массив
    47.         string [] split = str.Split(';');
    48.         //split[0] - text
    49.         //split[1] - md5
    50.         md5 = split[1];  
    51.     }
    52. }
    53. //Сравниваем массив хешей капч со страницы с хешем из базы
    54. for(int i=0; i<md5source.Length; i++)
    55. {
    56.     if(md5source[i] == md5)
    57.     {
    58.         //получим его индекс
    59.         index = i.ToString();
    60.     }
    61. }
    62.  
    63. //вернем индекс нужной нам капчи :)
    64. return index;
    65.  
    Делаем клик по соответствующей картинке :-)
     
    Last edited: Apr 24, 2014
    Emfortes, Roman*, wolfz and 22 others like this.
  5. izubr

    izubr Client

    Joined:
    May 11, 2011
    Messages:
    183
    Likes Received:
    47
    Очень неплохо. Зачет. Особенно для тех кто немного все таки дружит с программированием. Обязательно сохраню как мини мануал.
     
    masterLomaster and nomarketing like this.
  6. strannic

    strannic Client

    Joined:
    Dec 5, 2010
    Messages:
    211
    Likes Received:
    8
    Круто!
    Спасибо за качественный и понятный мануал!
    Даже не представлял что можно так разгадывать капчу :-)
    Главное чтобы база вопросов была не на лям.
     
  7. 7make

    7make Moderator

    Joined:
    Jun 25, 2011
    Messages:
    1,483
    Likes Received:
    1,158
    На этой капче было 40 уникальных картинок, и целесообразнее их руками забить в базу.
    На самом деле, если будет лям картинок, то можно на полном автомате составить базу.
    Точнее даже не базу, а алгоритм выбора нужной нам пары текст - хеш.
    Берем и сохраняем базу в таком формате:
    текст;md5(0);md5(1);md5(2);md5(3);md5(4);md5(5);md5(6);
    Мы точно знаем что один из 7 хешей точно верный для этого вопроса.
    Парсим таких строк некое кол-во. Я обычно беру факториал числа от кол-ва картинок.
    Если 7 картинок, я беру выборку 7! = 5040 =~6k строк
    А далее по такому алго обрабатываем.
    К примеру, просят выбрать самолет.

    1. Кидаем в массив хеши картинок с текущей капчи.
    2. Дергаем с файла базы в список=>массив temp все строки в которых есть текст вопроса
    3. Сравниваем попарно,и ищем пересечения, с условием что должно быть 1 пересечение значения в обоих массивах. Просто может быть другая картинка которая не соответствует вопросу, но она есть в обоих массивах. Если их больше чем 1(пересечений), берем другую строку.

    Можно реалтайм алгоритм использовать, можно отдельным проектом составить базу.
     
    Last edited: Apr 25, 2014
    sydoow, Lankorn, steamn and 4 others like this.
  8. Gerero

    Gerero Client

    Joined:
    Dec 20, 2010
    Messages:
    72
    Likes Received:
    64
    Отличная статья. Подозреваю что ТС уже давно успешно разгадывает кей капчу и другие виды "картиночных" капч.
     
  9. myweb101

    myweb101 Client

    Joined:
    Apr 29, 2013
    Messages:
    175
    Likes Received:
    29
  10. 7make

    7make Moderator

    Joined:
    Jun 25, 2011
    Messages:
    1,483
    Likes Received:
    1,158
    в той теме, ошибка в проекте.
    берете хеш для одной строки input в обоих случаях.
    ответил в теме
     
  11. smarchenko

    smarchenko Client

    Joined:
    Jan 18, 2014
    Messages:
    92
    Likes Received:
    7
    Аааа.. вот это статья =) ничего не понял, но как мне кажется это очень круто =) После ее прочтения понимаешь что зенопостер с C# бог
     
    BraG.A, Lankorn and GreenWay like this.
  12. zombie

    zombie Client

    Joined:
    Aug 14, 2012
    Messages:
    419
    Likes Received:
    58
    Спасибо за статью. Полезно!
     
  13. СамСебеСамса

    СамСебеСамса Client

    Joined:
    May 21, 2014
    Messages:
    129
    Likes Received:
    9
    мне кажется если так разбираться в си шарпе, то самому легко писать свои проги)
     
  14. lokiys

    lokiys Moderator

    Joined:
    Feb 1, 2012
    Messages:
    3,619
    Likes Received:
    816
  15. swiniks

    swiniks Client

    Joined:
    Feb 19, 2015
    Messages:
    219
    Likes Received:
    133
    Кто подскажет как из примера выше, когда считали картинку в переменную, тип как в примере выглядит base64 строка одной картинки из капчи. Как сохранить эту картинку в файл из переменной ??? использую zennoposter demo варианты через модуль капчи не подходят.
     
  16. swiniks

    swiniks Client

    Joined:
    Feb 19, 2015
    Messages:
    219
    Likes Received:
    133
  17. LexxWork

    LexxWork Client

    Joined:
    Oct 31, 2013
    Messages:
    1,194
    Likes Received:
    735
    System.IO.File.WriteAllBytes("путь", Convert.FromBase64String(toBitmap2));
     
  18. swiniks

    swiniks Client

    Joined:
    Feb 19, 2015
    Messages:
    219
    Likes Received:
    133
    LexxWork Спасибо! но System.IO.File.WriteAllBytes("путь", Convert.FromBase64String(toBitmap2));
    Не распознанная управляющая последовательность Ошибка !
    [​IMG] [​IMG]
     
  19. LexxWork

    LexxWork Client

    Joined:
    Oct 31, 2013
    Messages:
    1,194
    Likes Received:
    735
    @"c:\1.png"
     
  20. swiniks

    swiniks Client

    Joined:
    Feb 19, 2015
    Messages:
    219
    Likes Received:
    133
    УРА работает спасибо LexxWork
    Правильно так System.IO.File.WriteAllBytes("c:/1.png", Convert.FromBase64String(toBitmap2));
     
  21. LexxWork

    LexxWork Client

    Joined:
    Oct 31, 2013
    Messages:
    1,194
    Likes Received:
    735
  22. swiniks

    swiniks Client

    Joined:
    Feb 19, 2015
    Messages:
    219
    Likes Received:
    133
    Ну я путь то вначале скопировал с окна, а там наоброт слешь. Вот и ошибка выскочила, а так ещё не побывал @"c:\1.png" наверное тоже нужно вот так @"c:/1.png" :bt:
     
  23. Ilant

    Ilant Client

    Joined:
    Dec 25, 2015
    Messages:
    6
    Likes Received:
    0
    Добрый день!
    Ничего не понял, но чувствую что это то что мне нужно!
    Задача: Есть ссылка на товар интернет-магазина. Нужно спарсить ссылки на картинки + md5 картинок. В итоге должно получиться
    Code (text):
    1. <foto-remote url="http://site1.ru/pictures/image/1.jpg" md5="123456"/>
    Я смог спарсить картинки, но не могу получить их md5/

    Прошу, помогите!!:-)
     
  24. masterLomaster

    masterLomaster Client

    Joined:
    Jul 8, 2015
    Messages:
    2,751
    Likes Received:
    617
  25. masterLomaster

    masterLomaster Client

    Joined:
    Jul 8, 2015
    Messages:
    2,751
    Likes Received:
    617
    это всгда должно быть в топе, а то я потом найти немогу!:ay:
     
  26. BraG.A

    BraG.A Пользователь

    Joined:
    Aug 5, 2016
    Messages:
    77
    Likes Received:
    6
    Ни че не понятно) если б шаблон хотя бы был :D
     
  27. An_To_Ha

    An_To_Ha Client

    Joined:
    Sep 27, 2010
    Messages:
    18
    Likes Received:
    3
    А как такую капчу разгадать подобным образом
    [​IMG]
    капча похожая, только надо выбрать три варианта в ответе?
     
  28. masterLomaster

    masterLomaster Client

    Joined:
    Jul 8, 2015
    Messages:
    2,751
    Likes Received:
    617
  29. AZANIR

    AZANIR Client

    Joined:
    Jun 9, 2014
    Messages:
    262
    Likes Received:
    105
    отличная статья , пользуюсь данной темой не на одном сайте уже . класс автору респект!
     
  30. AZANIR

    AZANIR Client

    Joined:
    Jun 9, 2014
    Messages:
    262
    Likes Received:
    105
    задам тут вопрос
    проект работает без подгрузки картинок , и если через кубик указать что данная картинка капча , то в процессе работы , картинка подгружается , а если делать тоже самое сниппетом то вылетает ошибка и картинка не грузится.
     

Пользователи просматривающие тему (Пользователей: 0, Гостей: 0)