Создание серверных приложений на языке PERL

Облегчение поиска работы


Допустим Вы оказались без работы, развалилась ваша фирма или еще какая-нибудь причина. Вам требуется найти новую. Для упрощения этой задачи естьь следующий скрипт, который выцепливает по нужной позиции(веб программирование, зарплата от 200$ и т.д.) с www.job.ru все заявки за последние 10-15 дней, точнее емейлы, куда нужно слать резюме, что значительно убыстряет поиск работы(имея базы адресов легче разослать одно и то-же резюме, используя нехитрый список рассылки):

#!/usr/bin/perl -wT $url0="http://www.job.ru/cgi/list1.cgi?GR_NUM="; $url1="%31&TOPICID=9&EDUC=2&TP=&Gr=&SEX=&AGEMIN=23&AGEMAX=&MONEY=200&CDT="; $url2="&LDAY=99&ADDR=%ED%CF%D3%CB%D7%C1&KWORD=&KW_TP=AND"; use LWP::Simple; foreach($i=1; $i

Что делает эта программа, она составляет GET запрос из параметров, которые скрыты в hidden полях навигации по результатам запроса на www.job.ru. Программа при помощи Simple.pm отправляет запрос на сервер и как бы листает странички с поиском. Критерий ваших профессиональных навыков составлен в GET-запросе и осталось только разослать почту(для этого можно написать список рассылки) по адресам, которые выдала программа. Разберем регулярное выражение для вытаскивания почтового адреса из текущей странички s/(.*) ([\w+\-\.]+\@[\w\-\.]+\.\w{2,3})(.*)/$2/ig.

[\w+\-\.]\@ - найти все что содержит буквы, тире и точки до символа @, ведь почтовый адрес по спецификации может быть вида aa.ss-ss@chto-to.ru. Тоже самое после символа @ - [\w\-\.]+

далее может быть точка \. и любая буква от 2 до 3 символов \w{2,3}, т.е. окончание, самый верхний домен .com, .ru, .cz и т.д. Далее регулярное выражение состоит из трех классов скобок (.*) - переменная $1, ([\w+\-\.]+\@[\w\-\.]+\.\w{2,3}) переменная $2 и все остальное в (.*) - $3. Пробел перед $2 стоит потому, что так устроен html, отдаваемый пользователю поиском по базе предложений о работе www.job.ru. Нам нужно содержимое $2, в котором находится e-mail работодателя. Пишем его во вторую часть s/наш regex/$2/ig. Квантификатор i нужен для того, чтобы не различать регисты Vasya@pupkin.ru и vasya@pupkin.ru, квантиикатор g задействова на тот случай, если работодатель указывает 2 адреса, по которым нужно высылать резюме. На 23 августа 2001 года на 20 часов 10 минут прогамма выдала 410 e-mail адресов(пролистав за 3-4 минуты 57 страниц), где вас ждут, как потенциального сотрудника.


Остается написать скрипт почтовой рассылки по e-mails, выданным данным скриптом. Но это в другой главе.

Примером выше был получен спсиок email адресов. Теперь необходимо проверить, действительно ли существуют домены, на которых заведены такие пользщователи(примитивная - но проверка).

#!/usr/bin/perl use Socket; #загрузить inet_addr s{ # ( #Сохранить имя хоста в $1 (?: #Группирующие скобки (?! [-_] ) #ни подчеркивание, ни дефис [\w-] + #кусок имени хоста \. #и точка домена )+ #повторить несколько раз [A-Za-z] #следующий символ - буква [\w-]+ #домен верхнего уровня ) #конец записи $1 }{ #Заменить следующим: "$1" . #исходн часть + пробел (($addr = gethostbyname($1)) #Если имеется адрес ? "[" . inet_ntoa($addr). "]"#отформатировать : "[???]" #иначе пометить как сомнительный ) }gex

Переписываем исходную программу с учетом вышеприведенного кода

#!/usr/bin/perl -wT $url0="http://www.job.ru/cgi/list1.cgi?GR_NUM="; $url1="%31&TOPICID=9&EDUC=2&TP=&Gr=&SEX=&AGEMIN=23&AGEMAX=&MONEY=200&CDT="; $url2="&LDAY=99&ADDR=%ED%CF%D3%CB%D7%C1&KWORD=&KW_TP=AND"; use Socket; use LWP::Simple; foreach($i=1; $i

Между строчками можно комментировать целые куски кода. =pod $file=~s{((?:(?![-_])[\w-]+\.)+[A-Za-z][\w-]+)} {"$1".(($site=gethostbyname($1))?"[".inet_ntoa($site)."]":"[???]")}gex; print $file,"\n" if($file !~/\?\?\?/); =cut

Эта программа успешно удалила некторые из адресов, которые Socket.pm показались подозрительными. Все-таки какую-никакую, а проверку существования e-mail адресс окольными путями при помощи perl провести можно. Автору сего текста все-таки больше нравится вариант, заключенный в комментарии =pod(.*?)=cut. Он просто короче. Да и если научится читать сложные регулярные выражения, то можно написать полный регексп е-mail адресов, который занимается тем, что выделяет адреса в точности с соответствующим RFC(занимает это регулярное выражение несколько страгниц). Но впрочем ниже будет подглава, посвященная чтению монстрообразных, на первый взгляд, регекспов налету, со множеством примеров, выше же мы уже попытались угадать предназначение регулярного выражения только по его виду.

Ключи, которые использовались в вышеприведенном регулярном выражении



g - глобальная замена

е - выполнение

x - улучшенное форматирование.

Если написать это регулярное выражение в одну строчку, то оно врядли там поместится:

s{((?:(?![-_])[\w-]+\.)+[A-Za-z][\w-])}#здесь силовой перевод каретки {"$1".(($addr=gethostbyname($1))?"[".inet_ntoa($addr)."]":"[???]")}gex

Разберем один интересный момент в данном регекспе:

s/regex/условие?да:иначе/

Тут проявляется пожалуй одна из действительно сильнейших особенностей regex, возможность в одном регулярном выражении избежать многострочных условий с циклом. В приведенном примере работает все примерно так: Если $addr=gethostbyname($1) - да, то ставить ip-адрес(inet_ntoa($addr)), если нет(не откликнулся сервер, сбой на линии и пр) то метить этот урл как подозрительный [???]. В принципе в программе ничего человеку делать не нужно, т.к. подозрительные отметаются условием print $file,"\n" if($file !~/\?\?\?/); Общее время работы программы 10-15 минут.


Содержание раздела