Параллельные запросы

LexxWork

Client
Регистрация
31.10.2013
Сообщения
1 190
Благодарностей
791
Баллы
113
Привет вам, дорогие форумчане!
Как и в предыдущей статье я буду рассказывать о том что интересно мне и в итоге попытаюсь заинтересовать и Вас!

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

Говоря параллельных вычислениях я подразумеваю те способы или методы, реализованные в языках программирования, которые позволяют выполнять определенные параллельно, независимо друг от друга операции. В противовес можно поставить последовательные операции, а самым наглядным примером будет последовательность выполнения задач в шаблоне и многопоточное выполнение шаблона.
В принципе мультизадачность очень серьезная и обширная тема, а мне бы хотелось рассказать конкретные моменты, которые действительно можно применить в программе, когда есть такая возможность или желание.

Иногда так бывает, что перед шаблоном стоит задача просто получать данные с интернет-ресурсов, а потом что-то с ними делать. Очень часто эти задачи однотипные и в основном повторяются если не в цикле то в многопотоке шаблона.
Допустим, мне нужно собрать данные с определенного сайта, перебирая страницы с 1 по N. Обязательным условием должна быть возможность не использовать браузер и это очень важно. Обычная логика будет завернуть запрос и обработку в цикл и подкорректировать логику для возможности работы шаблона в многопотоке, если страниц много.
В принципе это нормально, но я нашел альтернативное решение с использованием параллельных циклов C# Parallel.For и Parallel.ForEach.

Теперь я постараюсь описать работу одного из трех шаблонов, которые будут в приложении. Перед нами стоит задача «выпарсить» весь список сайтов по домену высшего уровня с сайта domaintyper.com.
Для начала нам нужно подготовить данные, которые мы будем использовать для параллельного цикла.


int threads = int.Parse(project.Variables["threads"].Value);
var proxy = project.Variables["proxy"].Value;
string url = project.Variables["url"].Value;
var path = project.Variables["path"].Value;
int start_page = int.Parse(project.Variables["start_page"].Value);
project.Variables[
"start_page"].Value = (start_page + threads).ToString();
var regex = new System.Text.RegularExpressions.Regex("(?<=<tr\\sclass=\"wsTR[^<]*?<td>[^<]*?</td>[^<]*?<td>)[^<]+");
List<
int> emptypages = new List<int>();
List<
string> rlist = new List<string>();
int lastpage = 0;
int extracted = 0;

threads – отвечает у нас за количество «потоков», то есть сколько параллельных запросов мы собираемся сделать за раз.
proxy – адрес прокси если вдруг кому захочется поэкспериментировать. Сразу же говорю, скорость будет относительно медленней, так как данный пример не предусматривает использования уникальных прокси для каждого запроса в отдельности, но в принципе это возможно.
url - является корневой ссылкой, его значение можете увидеть открыв шаблон.
path отвечает за путь к файлу куда мы будем дописывать список
start_page – номер страницы с которой мы будем продолжать скачивать.
List<int> emptypages будет собирать те номера страниц где не удалось по какой-то причине обнаружить нужные нам строки.
List<string> rlist – главный список, в который мы будем складывать все найденные на странице сайты.
lastpage будет сигнализировать о том что мы дошли до последней страницы и дальше делать запросы не нужно.
extracted покажет сколько мы нашли ссылок на странице
А вот и сам параллельный цикл.


System.Threading.Tasks.Parallel.For(start_page, start_page+threads, p => {

___var response = ZennoPoster.HttpGet(url: url+p.ToString(), proxy: proxy, Encoding:"UTF-8", Timeout: 60000);
___List<string> domains = regex.Matches(response).Cast<System.Text.RegularExpressions.Match>().Select(s=>s.Value).Where(s=>s!="").ToList();
___project.SendInfoToLog(domains.Count.ToString(), p.ToString());
___rlist.AddRange(domains);
___extracted += domains.Count;
___if(response.Contains("<div class=\"pagingDivDisabled\">Next</div>")){
______emptypages.Add(p);
______if(domains.Count > 0){
_________lastpage = p;
_________project.SendInfoToLog("lastpage", p.ToString());
______}
___}
___else{
______if(domains.Count <= 0)
_________emptypages.Add(p);
___}
});

Метод Parallel.For работает как обычный цикл от start_page до start_page+threads только метод, который передается третьим параметром будет выполняться параллельно для каждого итератора p.
В этом методе производится запрос по адресу
url+p , вытаскиваются из ответа данные в список domains , а уже только после добавляем domains в результирующий - rlist.AddRange(domains) . Дальше идет определение, является ли наша страница последней и если нет, плюс добавляем в emptypages номер страницы, которая неудачно подгрузилась.
Завершение работы
Parallel.ForEach означает что мы скачали все страницы, обработали их, собрали все что можно в результирующие списки rlist и emptypages.
Все, что идет ниже параллельного цикла, это анализ, сохранение, логирование и вызов исключения в случае если
emptypages хранит в себе не ту страницу которую стоило ожидать последней на сайте.
В итоге мы получаем отдельный сниппет, который собирает для нас данные в параллельном режиме в один поток зеннопостера.
Два других шаблона работают по тому же принципу, но выполняют другие задачи.
ahrefs.com(top_domains).xmlz – может работать со списком прокси. Рекомендуемое число потоков от 50 до 1000;
gplusparser2.xmlz – скачивает аватарки на диск по ссылкам из уже подготовленного списка. Ставьте смело 10 000 потоков и смотрите что получится.

Вот и все. Удачи всем и спасибо за внимание!
 
Тема статьи
Другое
Номер конкурса статей
Третий конкурс статей

Вложения

Для запуска проектов требуется программа ZennoPoster или ZennoDroid.
Это основное приложение, предназначенное для выполнения автоматизированных шаблонов действий (ботов).
Подробнее...

Для того чтобы запустить шаблон, откройте нужную программу. Нажмите кнопку «Добавить», и выберите файл проекта, который хотите запустить.
Подробнее о том, где и как выполняется проект.

Последнее редактирование:

Nick

Client
Регистрация
22.07.2014
Сообщения
1 983
Благодарностей
817
Баллы
113
Спасибо, интересный метод! Конечно, нужно очень вдумчиво читать, чтобы понять, о чём вообще идёт речь. Мне пришлось прочитать пару раз от и до, чтобы врубиться :-)

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

Может быть, было бы проще, если бы объяснения по коду были бы сразу в виде комментариев внутри него, и если бы код был приложен как сниппет, отдельные строковые значения были вынесены в переменные с комментарием — короче, я бы максимально оптимизировал это для того, чтобы читатель мог как можно быстрее адаптировать этот сниппет для своих нужд. Может быть, внутрь метода, который исполняется в несколько потоков, добавить какое-то журналирование, чтобы можно было во время выполнения понять, что там происходит и «далеко ли до Таллина»?

Я не придираюсь, просто думаю, если чуть сильнее разжевать, можно дотянуться до более широких народных масс)) А так — интересно, спасибо!
 
  • Спасибо
Реакции: Roman*

LexxWork

Client
Регистрация
31.10.2013
Сообщения
1 190
Благодарностей
791
Баллы
113
Спасибо большое за критику. Да, действительно так все и есть. Альтернатива не всегда проста и элегантна. А кажушиеся плюсы могут вылезти в минусы.
На самом деле я долго думал на что действительно акцентировать внимание и кому это пригодится в принципе.
Насколько я знаю по аудитории форума, дело не в коментариях а просто в некоторого рода незнании. Не ради упрека, а из личного опыта общения с людьми, я понял, комментировать в коде нет смысла.
Основной посыл данной статьи не обучение языку а некоторого рода эксперементальность. Когда с помощью кувалды изобретают велосипед.
Но не все так плохо и неприменимо. Два шаблона из трех, которые я выложил, успешно используются человеком, у которого однопоточный зенопостер. А если честно-причестно, мое мнение насчет всего этого - чистый изврат в связи с некоторыми ограничениями.Серьезным программированием здесь не пахнет. Стыдно но все равно интересно.

Еще по поводу ограничений.
Если выполнять шаблон в многопотоке то внешний счетчик нужно выносить в глобальную переменную или файл. С глобальными перменными я вроде умею работать, но как показали тесты глобальные перменные очень ненадежны в начале инициализации и по окончанию работы шаблона. Использовать для этого дела файл значительно проще, но его нужно как-то инициализировать для правильной работы шаблона с самого начала, то есть писать в него вручную.
Еще можно просто набить счетчик в файл - действенно, но неприкольно. Другой момент это ограничения версий по потокам.
 
Последнее редактирование:
  • Спасибо
Реакции: todayer

Санёк

Client
Регистрация
30.08.2013
Сообщения
325
Благодарностей
111
Баллы
43
Да идея очень даже интересная, конечно не многим новичкам да и тем кто уже давно пользуется программой может стать понятно с первого раза сие чудо =) может даже и со 2-го и 3-его. В данном случае поддержу
Nick-а, комментарии в самом сниппете были ли бы более продуктивными, нежели описывать всё с низу. Уровень высокий, и интересный, заслуживает внимания. Спасибо автору за старания! Над оформлением можно ещё поработать, до результатов ведь ещё далеко?!))
 

surrealmix

Client
Регистрация
07.03.2013
Сообщения
715
Благодарностей
409
Баллы
63
Разве сайты не банят за чрезмерно частое обращение с одного ip (в 100500 потоков), ведь похоже на DDOS?
 

zortexx

Client
Регистрация
19.09.2011
Сообщения
2 520
Благодарностей
1 226
Баллы
113
На мой взгляд, использование C# сниппетов - это с одной стороны некий хак, позволяющий раскрыть и дополнить возможности программного комплекса, но с другой стороны чрезмерное использование сниппетов лишает смысла использования ZennoPoster. Потому что, в частности, тот же Visual Studio C# не накладывает обязательств по соблюдению потоков, лицензий разработчиков Zenno и не имеет неудобных ограничений на распространение, как, например, ZennoBox. Так что это палка о двух концах.

С одной стороны - приятно, что в однопоточном режиме программы можно работать фактически в любое количество потоков, но с другой стороны, становится очевидно, что для того чтобы окончательно избавиться от ограничений, нужно всего лишь сделать над собой усилие и полностью перейти на Visual Studio C# потратить некоторое время на стандартные заготовки, при помощи которых многие задачи в Zenno решаются из коробки.

И тут появляется еще одна проблема. Это новички использующие демо-версию программы, клянчащие C# сниппеты при помощи которых из демо-версии они фактически получают полноценный рабочий инструмент абсолютно бесплатно. А с использованием VirtualBox решается проблема ограничения демо-версии по времени.

Можно, конечно, переместить темы со сниппетами в скрытый раздел, или ограничить использование сниппетов в демо-версии, а то и совсем исключить возможность их использования, но как это повлияет на общее количество багов в программном комплексе в целом?

PS.: Статья интересная, но как я уже сказал выше, - возникает закономерный вопрос, - а зачем тогда нужен ZennoPoster? :-)
 

LexxWork

Client
Регистрация
31.10.2013
Сообщения
1 190
Благодарностей
791
Баллы
113
ну так, а браузер?, а списки, кубики... В студии снипеты не попишешь)
мой подход только для парсинга, в лучшем случае более сложных запросов.
 
  • Спасибо
Реакции: phirelli

KirillOFF

Client
Регистрация
18.12.2010
Сообщения
1 127
Благодарностей
517
Баллы
113

LexxWork

Client
Регистрация
31.10.2013
Сообщения
1 190
Благодарностей
791
Баллы
113

Nick

Client
Регистрация
22.07.2014
Сообщения
1 983
Благодарностей
817
Баллы
113
Я, честно говоря, тоже удивлён, что такой «хак» допустили на конкурс статей. Не удивлюсь, если в будущих билдах эту инструкцию Зенка в однопоточных версиях не будет компилировать (в многопоточных прошу оставить!). Вредит бизнесу.
 

LexxWork

Client
Регистрация
31.10.2013
Сообщения
1 190
Благодарностей
791
Баллы
113
это не хак ))) это простой функционал языка. Прошу не путать потоки зп и паралельные задачи. Уж очень велика разница.
 

AZANIR

Client
Регистрация
09.06.2014
Сообщения
405
Благодарностей
198
Баллы
43
это не хак ))) это простой функционал языка. Прошу не путать потоки зп и паралельные задачи. Уж очень велика разница.
мне статья понравилась, да насчет хака я сам недавно начал изучать С# и уже увидел млре плюсов которых нет в программе потому и тут скорее это плюс чем хак.
 

akademik

Client
Регистрация
06.08.2013
Сообщения
11
Благодарностей
1
Баллы
3
Спасибо за статью, но вопрос встает в чем, у меня pro версия, если я запущу пачку потоков, я проиграю в сравнении с этим способом?
 

LexxWork

Client
Регистрация
31.10.2013
Сообщения
1 190
Благодарностей
791
Баллы
113
не думаю что проиграете.
но если у вас в шаблоне будет допустим цикл который по порядку что-то выкачивает гетами от 0 до 100, то в паралельном цикле можно сделать 100 запросов сразу и ждать пока они все не прийдут.
 

Valiksim

Client
Регистрация
14.04.2012
Сообщения
1 344
Благодарностей
298
Баллы
83
На мой взгляд, использование C# сниппетов - это с одной стороны некий хак, позволяющий раскрыть и дополнить возможности программного комплекса, но с другой стороны чрезмерное использование сниппетов лишает смысла использования ZennoPoster. Потому что, в частности, тот же Visual Studio C# не накладывает обязательств по соблюдению потоков, лицензий разработчиков Zenno и не имеет неудобных ограничений на распространение, как, например, ZennoBox. Так что это палка о двух концах.

...

PS.: Статья интересная, но как я уже сказал выше, - возникает закономерный вопрос, - а зачем тогда нужен ZennoPoster? :-)
ZennoPoster всё больше становится элитарной программой или программой "для избранных". Для тех, кто шибко крут в программировании. Это, конечно же, "радует"...
 

svaminar

Client
Регистрация
21.08.2013
Сообщения
834
Благодарностей
379
Баллы
63
Не прав ты.
Просто чем больше пользуешься софтом тем более растет твой скил и более крутие фишки получаются.
А в реале 99 % проектов делаются максимально бистро без использования прогерских штук, с использованием набора шаблонов и циклов для быстрой разработки. Время на разработку намного на разработку дороже потоков.
 

alekwuy

Client
Регистрация
06.04.2013
Сообщения
1 631
Благодарностей
461
Баллы
83

ibred

Client
Регистрация
04.04.2015
Сообщения
3 835
Благодарностей
3 552
Баллы
113
Сижу изучаю "параллельные запросы", очень интересная тема.
Шлю лучи благодарности, отдал свой голос за статью ещё на старте голосования.

У меня вот только затыки, не понимаю, как реализовать: отправлять 3 GET запроса (параллельно) и получать ответ (содержание) в 3 разные переменные.
 

Nick

Client
Регистрация
22.07.2014
Сообщения
1 983
Благодарностей
817
Баллы
113
никак) а зачем?
 

orka13

Client
Регистрация
07.05.2015
Сообщения
2 177
Благодарностей
2 184
Баллы
113
Понадобилось тут мне скачать 9 млн картинок с разных источников (по списку урлов).

Переделал под себя gplusparser2.xmlz. результат очень порадовал. По сравнению с обычным GET-шаблоном скорость та же, при 160 потоках оба шаблона успевали загружать сетевой канал в 100 мбит. Но вот нагрузка на HDD при сохранении в разы меньше в gplusparser2.
 
  • Спасибо
Реакции: Nick

Nick

Client
Регистрация
22.07.2014
Сообщения
1 983
Благодарностей
817
Баллы
113
Офигенно) А хотелось бы оптимизировать или уже пофиг?
 

LexxWork

Client
Регистрация
31.10.2013
Сообщения
1 190
Благодарностей
791
Баллы
113
еще один пример - парсер группы вк, закрытый
кол-во потоков в настройках шаблона
в менедежере кол-во потоков 1
проработает 10 дней от 26.06
подойдет для всех версий не ниже 5.7.5.3

vk_mparser_MT_limited.xmlz
 

Вложения

ssXXXss

Client
Регистрация
23.12.2014
Сообщения
7 379
Благодарностей
2 041
Баллы
113
Появилось время и сделал параллельный запрос под свой шаблон, результат хорошо порадавал.
 

Shapito

Новичок
Регистрация
02.04.2016
Сообщения
29
Благодарностей
2
Баллы
3
Заранее извиняюсь, не совсем понимаю о чем печь, только осваиваю программу и в программировании ноль. Ваш метод позволяет запустить Project Maker в несколько потоков? Если да, то в каких версиях (Lite, Standart, Demo)это возможно?
 

Radzhab

Client
Регистрация
23.05.2014
Сообщения
1 500
Благодарностей
1 268
Баллы
113
Этот метод позволяет запускать многопоток даже в демке) Ключевое слово "метод". Он не запускает PM в несколько потоков
 
  • Спасибо
Реакции: AZANIR

AZANIR

Client
Регистрация
09.06.2014
Сообщения
405
Благодарностей
198
Баллы
43
Этот метод позволяет запускать многопоток даже в демке) Ключевое слово "метод". Он не запускает PM в несколько потоков
отличная вещь , автору респект , использовал просто колосально экономит ресурсы и время.
 

Nikitos

Client
Регистрация
15.09.2016
Сообщения
46
Благодарностей
6
Баллы
8
Этот метод позволяет запускать многопоток даже в демке) Ключевое слово "метод". Он не запускает PM в несколько потоков
Добрый день, у меня zenoposter lite (на pro пока не накопил) нужно запустить 3 проекта, и как я только не изворачиваюсь... Запускаю один проект в PM, другой в Zennopostere, иногда отключаю один проект в ZP, запускаю 3-й. Если нужно что то изменить в проекте, приходится останавливать выполнение выполнение шаблона в PM, загружать туда шаблон который нужно редактировать, изменяю его, запускаю в PM проект, кароче гимарой еще тот. Подскажите, как с помощью этого сниппета я могу решить свою проблему?
 

shved2

Client
Регистрация
16.07.2015
Сообщения
146
Благодарностей
53
Баллы
28
Добрый день, у меня zenoposter lite (на pro пока не накопил) нужно запустить 3 проекта, и как я только не изворачиваюсь... Запускаю один проект в PM, другой в Zennopostere, иногда отключаю один проект в ZP, запускаю 3-й. Если нужно что то изменить в проекте, приходится останавливать выполнение выполнение шаблона в PM, загружать туда шаблон который нужно редактировать, изменяю его, запускаю в PM проект, кароче гимарой еще тот. Подскажите, как с помощью этого сниппета я могу решить свою проблему?
Этот сниппет вам не поможет.
Берите стандарт или про версию.
 
  • Спасибо
Реакции: Zarkiy

Sergodjan

Administrator
Команда форума
Регистрация
05.09.2012
Сообщения
20 407
Благодарностей
9 116
Баллы
113
Добрый день, у меня zenoposter lite (на pro пока не накопил) нужно запустить 3 проекта, и как я только не изворачиваюсь... Запускаю один проект в PM, другой в Zennopostere, иногда отключаю один проект в ZP, запускаю 3-й. Если нужно что то изменить в проекте, приходится останавливать выполнение выполнение шаблона в PM, загружать туда шаблон который нужно редактировать, изменяю его, запускаю в PM проект, кароче гимарой еще тот. Подскажите, как с помощью этого сниппета я могу решить свою проблему?
как вариант купить еще одну доп. копию проджект-мейкера за 500 руб..
почти шутка, но в каждой шутке, как говорится.....
 

ssXXXss

Client
Регистрация
23.12.2014
Сообщения
7 379
Благодарностей
2 041
Баллы
113
как вариант купить еще одну доп. копию проджект-мейкера за 500 руб..
почти шутка, но в каждой шутке, как говорится.....
тогда пару зенобоксов лучше, в РМ править и в бокс заливать, например у меня 10 боксов с пустыми проектами прикупить )))))) будет у тя 10 боксов по 20 потоков и гоняй потом, насчёт 10 шучу и на счёт себя тоже, но так же почти шутка, но в каждой шутке, как говорится.....
 

Кто просматривает тему: (Всего: 3, Пользователи: 0, Гости: 3)