Сейчас трудно найти более-менее популярный сайт, где бы важные для сайта, запросы (голосование, подтверждение перевода денег итд ) формировались через переданные сервером в явном виде данные. Подобные действия со стороны администрации и программистов сайта ясны - они хотят максимально усложнить процесс копирования запроса браузера. Обычно для усложнения данных запроса на клиентской стороне используеться JavaScript и как правило этот скрипт не так уж легко понять (200-1000 строчек хрензнаеткакнаписанного кода): сервер посылает гипер-текстовую страницу с вкраплениями JS и исходных данных JS обрабатывает переданные в явном виде данные и формирует из них данные для верификации запроса браузер дает запрос серверу с целевыми аргументами и аргументами для верификации запроса сервер анализирует полученные данные верификации запроса и если они удовлетворяют требованиям, то обрабатывает целевые Мой способ обойти подобные сложности не претендует на изящность или сверхскорость, однако он рабочий и более-менее универсальный, а самое главное не придеться разбирать JS. Далее я опишу этот способ на примере накрутчика голосования. Итак, у нас имеется сайт с голосованием, где: в течении 24-х часов с одного ip-адреса можно проголосовать только 1 раз данные запроса к серверу содержат кукисы, целевое значение(номер позиции, за которую я проголосовал), данные верификации запроса (формируются посредством 750-строчного JS-кода закодированного всеми возможными base64, а так же какими-то своими способами кодирования и все это разбавлено максимально непонятным стилем программирования). Ограничение с ip-адресом мы обходим за счет проксиков/tor/итд, собрать сам AJAX/POST-пакет с кукисами и целевыми параметрами мы тоже легко можем, однако как быть с параметрами формируемыми JS. Первая мысль, конечно, была - разобрать сам JS код, но как показала практика это того не стоит. Второй вариант - найти/написать самому интерпритатор JS с поддержкой DOM, но писать самому это очень долго, а существующие решения весьма карявые и сильно не дотягивают до интерпритаторов современных браузеров. Третьей мыслью и был как раз мой способ. 1. Web-сервер Нам нужно либо написать свой HTTP-сервер, либо воспользоваться уже существующим. Код для формирования страниц там будет очень легкий, поэтому жизнеспособны оба варианта. Я воспользовался чем-то средним между двумя этими вариантами - библиотека-сервер Webrick. Скрипт написан на Ruby. Code: #!/usr/bin/ruby require 'webrick' include WEBrick require 'net/http' # глобальный массив браузеров, дабы не вызвать подозрений $user_agents=['Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/$$v$$ (.NET CLR 3.5.30729)', 'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.17) Gecko/2010010604 Ubuntu/9.04 (jaunty) Firefox/$$v$$', 'Mozilla/5.0 (Windows; U; Windows NT 5.1; ru; rv:1.9.1.7) Gecko/20091221 MRA 5.5 (build 02842) Firefox/$$v$$', 'Mozilla/5.0 (Windows; U; Windows NT 5.1; ru; rv:1.9.0.7) Gecko/20191231 MRA 5.4 (build 02842) Firefox/$$v$$', 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; WebMoney Advisor)', 'Opera/9.80 (Windows NT 5.1; U; MRA 5.5 (build 02842); ru) Presto/2.2.15 Version/$$v$$', 'Opera/9.80 (Windows NT 6.1; U; ru) Presto/2.2.15 Version/$$v$$', 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/$$v$$; GTB6.4; InfoPath.2; .NET CLR 1.1.4322)', 'Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US) AppleWebKit/532.5 (KHTML, like Gecko) Chrome/$$v$$.249.78 Safari/532.5', 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; GTB6.4; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729)', 'Mozilla/5.0 (X11; U; Linux i686; en; rv:1.9.0.17) Gecko/20080528 Epiphany/$$v$$ Firefox/3.0', 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/532.5 (KHTML, like Gecko) Chrome/4.0.249.78 Safari/532.5', 'Opera/9.64 (Windows NT 6.0; U; ru) Presto/2.1.1', 'Lynxy/6.6.6dev.8 libwww-FM/3.14159FM', 'PycURL/7.18.2', 'Opera/9.51 (Windows NT 6.0; U; en)'] # хэш замен $replace={"/konkurs"=>"http://kakoi-nit.oprosnik.ru/konkurs"} # совершенно не обязательная перегрузка функции get из Net::HTTP, увеличивает шансы что страница будет загружена, хотя и без нее шансы не малы class Net::HTTP def my_get(path,headers) begin return self.get(path,headers) rescue TimeoutError sleep(1) retry rescue Errno::ENETUNREACH sleep(10) retry else sleep(1) retry end end#def end#class # формирует User-agent запроса посредством глобального массива $user_agents def get_user_agent return $user_agents[rand($user_agents.size-1)].gsub('$$v$$',"#{(rand(10)+1)}.#{(rand(10)+1)}") end # формирует заголовок запроса def get_headers() headers = { 'User-agent'=> get_user_agent, 'Accept'=> 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 'Accept-Language'=> 'ru,en-us;q=0.7,en;q=0.3', 'Accept-Charset'=> 'UTF-8,*', 'Keep-Alive'=> '300', 'Connection'=> 'keep-alive'} return headers end # чисто webrick'овская примочка, создает еще один поток который ожидает на ввод 'q\n' чтобы завершить работу сервера th=Thread.new do while true do if STDIN.gets.chop=="q" then exit! end end end # конфигурируем и запускаем сам сервер webrick config={} config.update(:Port => 8080) server = HTTPServer.new(config) ruby_dir = File.expand_path('www') server.mount("www", HTTPServlet::ERBHandler, ruby_dir) # делаем сервелет для webrick server.mount_proc('/js-miracle') do |req,resp| # получаем страницу голосования с интересуещего нас сайта http=Net::HTTP.new('kakoi-nit.oprosnik.ru', 80) respp, data = http.my_get("/konkurs/super-golosovanie",get_headers) # передаем куки resp['Set-Cookie']=respp['set-cookie'] #ВНИМАНИЕ ЗДЕСЬ ВСЯ ФИШКА # заменяем часть строки исходной страницы на нужный нам код data.gsub!("href=\"javascript: create_verified(0);\"","href=\"javascript: create_verified(0);\" id=\"jslink\"") data.gsub!("konkurs/images/vote.png\" alt=\"\" /></a>", "konkurs/images/vote.png\" alt=\"\" /></a><script type=\"text/javascript\"> document.getElementById('jslink').onclick();</script>") #ФИШКА ЗАКОНЧИЛАСЬ # меняем адреса ссылок с относительных на kakoi-nit.oprosnik.ru # на абсолютные на kakoi-nit.oprosnik.ru посредством хэша замен $replace $replace.each {|k,v| data.gsub!(k,v)} # передаем страницу resp.body=data end # запускаем сервер server.start Теперь разберемся. Во-первых не надо пугаться webrick и Ruby это чисто мой выбор, можно использовать абсолютно любую связку PHP+Apache, PHP+Denver итд вплоть до написания своего маленького однопоточного сервера на C или Delphi. Сервелет это что-то типа странички на PHP или ERB, я выбрал его дабы не заморачиваться и писать меньше кода, однако PHP или его аналог ни в чем ему не уступит. Как это работает и зачем оно нужно: вы запускаете сервер и открываете браузер на странице http://127.0.0.1:8080/js-miracle сервер получив ваш запрос, отправляет запрос на сервер kakoi-nit.oprosnik.ru c целью получить страничку голосования /konkurs/super-golosovanie, иначе говоря заходит по адресу http://kakoi-nit.oprosnik.ru/konkurs/super-golosovanie. берет полученные от kakoi-nit.oprosnik.ru куки и вкладывает их в ответ вашему браузеру в секторе про ФИШКУ мы заменяем или добавляем наш JS код т.е. допустим при нажатии на кнопку 'голосовать' управление передаеться в JS функцию formirovanie_verified_parameters(), в которой к параметрам формы добавляеться всякая фигня для верификации (заполнение скрытых полей, добавление новых кукисов итд) без которой kakoi-nit.oprosnik.ru воспримит наш следующий запрос как фальшивый. Конечно, мы можем каждый раз вручную нажимать на кнопку 'голосовать' но мы же автоматизируем, поэтому мы вставляем сюда код, который при загрузке страницы имитирует нажатие на эту кнопку, причем дальше браузер сам выполнит все как нужно, как будто мы это сделали вручную. В данном случае у нас есть картинка konkurs/images/vote.png, которая вложена в тэг ссылки <a href="javascript:create_verified()"><img src="konkurs/images/vote.png\" alt=\"\" /></a> и при загрузке нам нужно на нажать на картинку, чтобы активизировать ссылку, но чтобы это сделать нам сначало нужно как-то идентифицировать ссылку поэтому мы добавляем ей параметр id="jslink". А затем, добавлем сам код нажатия <script type="text/javascript\"> document.getElementById('jslink').onclick();</script>"). меняет ссылки со всех картинок, css-таблиц, js-файлов итд с относительных kakoi-nit.oprosnik.ru на абсолютные http://kakoi-nit.oprosnik.ru/example_page.html. Короче говоря, когда он получит страницу с kakoi-nit.oprosnik.ru большинство ссылок там будут иметь вид /link/path/to/object.js, и если наш браузер получит страницу с таким путем ссылок, то он будет просить этот ресурс у нашего сервера (webrick), а у нас их нет, зато они есть у kakoi-nit.oprosnik.ru, поэтому мы меняем их на http://kakoi-nit.oprosnik.ru/link/path/to/object.js. заполянем html-тело ответа нашему браузеру в точности такое же как страница http://kakoi-nit.oprosnik.ru/konkurs/super-golosovanie за исключением смены адресов ссылок и изменение/добавление JS-кода. В итоге в браузере мы получаем точно такую же страницу как http://kakoi-nit.oprosnik.ru/konkurs/super-golosovanie, с теми же самыми куками и параметрами верификации + наш личный JS-код нажатия на кнопку/ссылку, короче код автоматизации процесса. 2. Обход бана по ip Нам нужно выбрать какой-нить браузер, где можно установить так: не использовать прокси/socks/tor/итд для 127.0.0.1 использовать прокси/socks/tor для всех остальных Этим требованиям отлично удовлетворяет FireFox. Лично я не стал заморачиваться с проксями а решил использовать tor: поднимаем локальный проксик privoxy устанавливаем tor в настройках прокси FF ставим адрес и порты privoxy, чаще всего это бывает так 127.0.0.1:8118. Далее ставим домашнюю страницу на наш локальный web-сервер (webrick) т.е. http://127.0.0.1:8080/js-miracle Теперь при запуске вашего браузера он сам будет выполнять все нужные действия т.е. вам нужно только нажать на ярлык браузера и будет отсылаться нужный вам запрос 3. Автоматизация запуска браузера Поскольку нам нужно отправлять миллионы таких запросов разумно было бы зациклить запуск и закрытие браузера. Это можно сделать как угодно, для linux это может быть bash-скрипт, для windows - bat-файл или на худой конец скрипт любого ЯП. Я выбрал 'худой конец' (скрипт написан на Ruby, Linux): Code: #!/usr/bin/ruby lim=200 sleep_time=50 def my_sleep (sl) for i in 0..sl sleep(1) print '.' STDOUT.flush end end for i in 0..lim do puts "browser start" system("firefox http://127.0.0.1:8080/js-miracle &") my_sleep sleep_time puts "\n kill start" system("killall firefox") end Замечания и примечания После запуска сервера и последнего скрипта каждые 50 секунд будет открываться FF автоматически выполняя вашу задачу, процесс будет повторяться 200 раз т.е. будет отправлено 200 запросов или 200 голосов в голосовании будет за меня. Поскольку постоянное мелькание браузера может раздражать пользователям *nix рекомендую заменить firefox на консольный links, и мелькание прекратиться. Пользователям windows не знаю что посоветовать, кроме как сделать окно FF мимнимального размера. Что касаеться tor и privoxy, они далеко не обязательны, с ними удобнее, однако по скорости они заметно уступят приватным проксям. Для того чтобы сделать все через прокси, нужно будет использовать такие упаковщики трафика как proxychains и widecap итд. Однако так как они не будут разбираться к какому хосту обращаеться браузер и упаковывают весь трафик, их нужно будет либо настроить на то чтобы не применялись прокси для localhost, либо разместить наш сервер на каком-нить бесплатном хостинге или еще где угодно, главное чтобы не в нашей подсети. Теперь относительно периода открывания браузера. Я взял 50 секунд, иногда этого много, а иногда мало, в зависимости от выбранных нодов тора. Оптимизаторам следует, конечно, выбирать не постоянный период а вычислять прогрузился ли сайт в браузере или нет, и соответсвенно после того как браузер все сделал закрывать его. Вся эта штука тестировалась, запускалась и работала только под линуксом, однако все должно работать и под виндой, за исключением скрипта автоматизации запуска браузера, но для винды легко пишеться bat-файл. Выводы и итоги Этот принцип не отличаеться изящностью и быстродействием, однако он очень универсален, его можно применять далеко не только для опросов. Он хорошо работает для обхода капчи, где верификация капчи проходит через AJAX, парсинга тех сайтов, где админы очень любят все запутать, например списка проксиков, короче он применим везде где вам не нравиться тот или иной JavaScript на странице сайта. И еще раз обнадежу, весь код приведенный здесь не играет никакого приципиального значения, он целиком и полностью заменяеться аналогичным на PHP, С, Delphi итд. P.S. когда мне будут вручать приз как победителю голосования выложу фотки с церемонии награждения ))