Часто замечаю на форумах просьбы дать инвайт/аккаунт к какому-нибудь ресурсу, причем многие ресурсы не обладают никакой защитой от перебора пароля. Скрипт для сбора логинов с ресурса (если это возможно) и последующего перебора пишется минут за 10. Непонятно что людям мешает взять и самостоятельно набрать аккаунтов к необходимому ресурсу, ибо в гугле встречается довольно много простых примеров использования потоков и выполнения запросов к серверу.
Парсер (в качестве примера для сайта torrents.ru, полный код парсера приведен в конце статьи):
Для начала разберемся откуда можно набрать список логинов.
Регистрируемся на трекере и смотрим как выглядит ссылка на профиль: http://torrents.ru/forum/profile.php?mode=viewprofile&u=XXXXXXX (где XXXXXXX некоторое число). Соответственно собирать будем, пролистывая список пользователей по цифровому идентификатору.
Теперь начнем писать сам парсер:
1 2 3 4 5 |
use warnings; use LWP::UserAgent; #Компонент для осуществления веб запросов use HTTP::Cookies; #Компонент для работы с кукисами use threads; #Компонент для работы с потоками use threads::shared; |
Объявим несколько переменных:
1 2 |
my $i : shared = 5000000; # Ид страницы с котороый начать парсинг, суффикс shared делает переменную общей для всех потоков my $threads = 9; # Количество потоков |
Создадим компонент браузера и прикрепим к нему контейнер кукисов:
1 2 3 |
my $ua = LWP::UserAgent->new(); my $ck = HTTP::Cookies->new(file => 'cookies.dat', autosave => 1); $ua->cookie_jar($ck); |
На сайте torrents.ru для просмотра профиля необходимо авторизоваться на сайте, соответственно произведем авторизацию логином и паролем, которые мы создали раньше:
1 2 3 4 5 6 |
$ua->post('http://torrents.ru/forum/login.php', #Url пост запроса формы авторизации {#Далее идет перечисление пар: 'переменная с сайта' => 'необходимое значение' 'login_username' => 'MyLogin', 'login_password' => 'MyPassword', login => 'Вход' }); |
Url пост запроса и пары переменных можно посмотреть с помощью сниффера (например Wireshark) или специального плагина для браузера (например Tamper Data для Mozilla Firefox). Либо Вы можете открыть страницу с полями авторизации http://torrents.ru/forum/index.php и посмотреть в исходном коде необходимые пути и переменные, в случае с torrents.ru это:
1 2 3 4 |
<form action="./login.php" method="post"> #./login.php - url авторизации относительно http://torrents.ru/forum/ <input type="text" name="login_username" #Поле логина <input type="password" name="login_password" #Поле пароля name="login" value="Вход" #Поле указывающее на авторизацию |
Далее создадим потоки (создается количество потоков от 0 до значения переменной $threads, каждый поток выполняет функцию с именем Brut, в каждый поток передается переменная с его порядковым номером, которая понадобится позже):
1 2 |
for(0..$threads) {$trl[$_] = threads->create(\&Brut, $_);} for(@trl) { $_->join; } |
Теперь код парсинга и сбора информации:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
sub Brut { #Название функции my $fid = $_; #Переменная с номером потока(используется позже для того чтобы каждый поток писал в отдельный файл while($i>0) #Создаем цикл, который будет выполнятся пока ид страницы > 0 { my $url = ""; #Создаем пустую переменную $url { lock($i);$i--; #Блокируем переменную $i для данного потока и уменьшаем её значение на 1 print "$i\n"; #Выводим на экран текущее значение $i $url = "http://torrents.ru/forum/profile.php?mode=viewprofile&u=$i" # Присваиваем переменной $url адрес страницы для дальнейшего парсинга } $res = $ua->get($url)->as_string; #Получаем страницу в переменную $res if ($res =~ /Профиль пользователя: (.*?)<\/h1>/) #Регулярным выражением вытаскиваем из текста страницы логин пользователя { open(FILE, ">>$fid.log.txt") || die("Could not open $fid.log.txt\n"); #Открываем файл для дозаписи print FILE $1."\n"; #Записываем в файл полученный с помощью регулярного выражения логин пользователя close(FILE); #Закрываем файл } } } |
Несколько пояснений относительно кода выше:
имя файла вида $fid.log.txt нужно чтобы каждый поток писал в отдельный файл (судя по моим наблюдениям - меньше грузит систему, чем работа с одним общим файлом);
Регулярное выражение /Профиль пользователя: (.*?)<\/h1>/
получено исходя из страницы профиля пользователя, т.к. логин пользователя содержится между строками "Профиль пользователя: "
и "</h1>"
, то мы пишем выражение, забирающее весь текст между ними (обратный слеш перед /h1>
необходим, чтобы компилятор не считал /
закрывающим в регулярном выражении, строка (.*?)
забирает любое количество произвольных символов от выражения слева от скобок до выражения справа) .
Исходники парсера: скачать
То что нада ;) ппц тока сеня сутра хател подумать как написать этот парсер а тут наткнулся на твой сайт %)Пасиба)
учишь юных кодеров быдлокоду? ))
исходник парсера не пашет... ((
А ты валидный логин и пароль в соответствующей строке вписать не забыл?
нет, не забыл, сам проверь, может что то упущено
Только что запустил, все нормально работает
прошу прощения, а скрипт ещё актуален? фактически нужен только парсер... ввожу рабочие лог и пасс, выдаёт ошибку: "Ошибка сегментирования".
Это на какой ОС такое выдает? Под win с activeperl все нормально работает
Ось - linux 2009.0 mandriva, ядро 2.6.27.14
в windows xp с ActivePerl 5.10.0.1004, выдаёт критическую ошибку и закрывает приложение perl.exe
Не представляю как ты её ловишь, может ты там много потоков поставил конечно, а так не знаю.
да нет... потоков больше 10 не ставил, хотя и при 1 та же фигня, ладна, буду разбираться, в любом случае спасибо! =)
Это актуально еще?
Поидее да
I will be linking to your site great article.
В рот мне килограмм печенья!
Хотел раскрутить сайт для пожертвования на Никольский храм.
Но парсер не работает! Может торрент отказывается помогать пожертвованию или изменил вообще структуру работы. нужна ваша помощь Никольскому храму в строительстве. Кто сделает рекламу!?
парсер все еще актуален?у меня не работает.
текстовый файл нужно самому создавать?
Фиг знает, вполне могло что-то измениться. Файл создавать не нужно
Спустя 3 года не актуально еще?)
Ещё? Скорее уже
Так актуален урок или нет?
С точки зрения работоспособности получившегося кода - нет