GetInfo.Ru – Компьютерная библиотека
Последние поступления
Как выбрать систему управления базы данных
Базы данных03/09/14
Этапы загрузки UNIX (в схеме)
Unix27/03/12
Gatewall Antispam: тотальный контроль электронной почты
Спам21/04/11
Мастер-класс: создаем Интернет-магазин (Часть 1)
Обзоры ПО20/04/11
CorelDRAW Graphics Suite X5: Что нового?
Обзоры ПО20/07/10
Добавить статью
Самые читаемые материалы
Проверка e-mail адреса на существование(32433)
Строим календарь для сайта на Perl(11834)
Web Основы с LWP(11458)
Построение крупно-масштабного e-commerce сайта на Apache и mod_perl(11306)
Image::Magick или фотошоп для perl(9700)
Всего статей: 793Всего авторов: 364Подразделов: 47Добавлено за сутки: 0
Статьи  СТАТЬИ Форум  ФОРУМ Рейтинг  РЕЙТИНГ Поиск  ПОИСК Контакты  КОНТАКТЫ
» Главная » Perl » Perl :: LWP + MIME или как получить WEB страницу по почте

Perl :: LWP + MIME или как получить WEB страницу по почте


Vladimir Maximenko
4raznoe@mail.ru
http://takiedela.narod.ru/

В этой статье будет рассказано о том, как используя модули Perl LWP::UserAgent и MIME::Lite скачать HTML страницу и отослать ее в письме вместе со всеми вложенными изображениями.

Применяя изложенный метод я ежедневно получаю свежие анекдоты в свой почтовый ящик - ну лень мне каждый день лазить в Инет :-)

Для работы нам потребуются следующие модули (взять их можно на CPAN http://www.cpan.org)

  • LWP::UserAgent - класс пользовательских агентов WWW
  • MIME::Lite - облегченный MIME кодер/декодер
  • URI::URL - работа с URL
  • HTML::LinkExtor - получение списка всех URL в документе
  • Time::Local - преобразует компоненты полного времени в секунды

Для примера разберем, как выкачиваются все истории за день с сайта "Анекдоты из России" http://www.anekdot.ru.

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

Адрес нужной нам страницы строится следующим образом :

 сайт анекдотов/an/an год месяц/o год месяц день .html

причем от года берутся только 2 последние цифры, а месяц и день дополняется до 2 символов нулями слева, если это необходимо.

Таким образом, страница
http://www.anekdot.ru/an/an0206/o020629.html содержит все истории за 29 июня 2002 года.

Небольшое лирическое отступление для тех, кто только начал осваивать Perl.

Как скачать WEB страницу ?
require LWP::UserAgent;
$ua = LWP::UserAgent->new;

$ua->proxy(['http', 'ftp'], 'адрес прокси-сервера');
$req = new HTTP::Request('GET' => 'страница для скачивания');

if ($res->is_success) { $page = $res->content; }
Как отправить письмо с прикрепленными файлами?
require MIME::Lite;
$msg = MIME::Lite->new(
   From =>'Ваш@Адрес.com',
   To =>'Адрес@Получателя.com',
   Subject =>'Тема сообщения',
   Type => 'multipart/related');

$msg->attach(
   Type =>'text/plain; charset=windows-1251',
   Data => текст письма);

$msg->attach(
   Type => 'image/gif', 
   Path => путь к файлу, 
   Filename =>'img.gif');
$msg->send();

Рассмотрим по шагам работу программы.
  • Определяем URL документа
  • Скачиваем содержимое WEB страницы
  • Ищем и скачиваем все содержащиеся на странице изображения
  • Меняем ссылки относительно документа на их абсолютное значение
  • Присоединяем внешние файлы CSS,JavaScript
  • Кодируем все изображения и собираем MIME объект
  • Отсылаем получившееся письмо по электронной почте

Техническую реализацию скрипта я буду описывать схематически, если что будет не понятно - смотрите исходник.

C ANEKDOT.RU все истории за вчера. Вычисляем дату - полночь вчерашнего дня. Дополняем дату нулями слева.

 $sutki=24*60*60;
 ($tek_day,$tek_month,$tek_year)=(localtime)[3,4,5];
 $in1=timelocal(0,0,0,$tek_day,$tek_month,$tek_year);
 $in2=$in1-$sutki;
 ($tek_day,$tek_month,$tek_year)=(localtime($in2))[3,4,5];
 $tek_month++; $tek_year+=1900;
 if ($tek_month<10) {$tek_month="0".$tek_month}
 if ($tek_day<10) {$tek_day="0".$tek_day;}
 $an_year=substr($tek_year, 2, 2);

 

Страница для скачивания. Определяем адрес страницы согласно приведенного шаблона.

$url_page="http://www.anekdot.ru/an/an".$an_year.$tek_month."/o".$an_year.$tek_month.$tek_day.".html";

 

Скачиваем содержимое страницы используя модуль LWP.

 if ($url_page && $url_page=~/^(https?|ftp|file|nntp):\/\//)
 {
  my $req = new HTTP::Request('GET' => $url_page);
  my $res = $ua->request($req);
  $gabarit = $res->content;
 }

Подключаем внешний CSS и JavaScript. Тут все очень упрощенно показано, но разобраться можно - качаем файл со скриптами и подставляем его в нужное место HTML документа.

внешний CSS = '<style type="text/css">'."\n".'<!--'."\n". файл со стилями ."\n-->\n</style>\n"; документ HTML =~s/<link([^<>]*?)href="?([^\" ]*)"?([^>]*)>/ внешний CSS /iegmx; внешний JavaScript = '<script><!--'."\n". файл со скриптами ."\n-->\n</script>\n"; документ HTML =~s/<script([^>]*)src="?([^\" ]*js)"?([^>]*)>/ внешний JavaScript /iegmx;

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

 my $analyseur = HTML::LinkExtor->new;
 $analyseur->parse($gabarit);
 my @l = $analyseur->links;
   
 foreach my $url (@l)
 {
  my $urlAbs = URI::WithBase->new($$url[2],$racinePage)->abs;
  chomp $urlAbs;
  
  if( ($$url[0] eq 'a') && ($$url[1] eq 'href') 
      && ($$url[2]) && (($$url[2]!~m!^http://!) 
      && ($$url[2]!~m!^mailto:!)) )
  {
   $gabarit=~s/\s href= [\"']? $$url[2] [\"']?/ href="$urlAbs"/gimx;
  }
 }

Выбираем из документа все изображения, скачиваем картинку, определяем тип и возвращаем ее, закодированную в MIME.

 if ( ((lc($$url[0]) eq 'img') || (lc($$url[0]) eq 'src')) )
 {
  push(@mail, create_image_part($urlAbs));
 }
 if (lc($ur)=~/gif$/) {$type="image/gif";}
 elsif (lc($ur)=~/jpg$/) {$type = "image/jpg";}
 else { $type = "application/x-shockwave-flash"; }
 my $res2 = $ua->request(new HTTP::Request('GET' => $ur));
 $buff1=$res2->content;
 $file_name = substr($ur,rindex($ur,"/")+1,length($ur));
   
# кодируем очередную картинку
 my $mail = new MIME::Lite(Data=>$buff1,Encoding=>'base64','Filename'=>$file_name);
 $mail->attr('Content-type'=>$type);
 $mail->attr('Content-Location'=>$ur);

Создаем MIME объект, указываем от кого и кому письмо, тему сообщения. Если на странице изображений нет - тип сообщения text/html, если есть картинки - multipart/related.

 $mail = new MIME::Lite 
   'From' => 'somebody@somewhere.com',
   'To' => $to_email,
   'Subject' => $url_page,
   'Data' => $html;
 $mail->attr("Content-type" => $content_type);
 if (@mail)
 {
  $mail->replace("Type" => "multipart/related");
# присоеденяем каждую картинку
  foreach (@mail) {$mail->attach($_);}
 }

Отсылаем страницу по почте. Можно использовать SMTP или sendmail.

MIME::Lite->send('smtp', " адрес SMTP сервера ", Timeout=>60);
$mail->send(); 

Выполнение программы.

Помещаем наш скрипт в каталог, откуда разрешено выполнение программ и делаем файл исполняемым

 chmod 750 /usr/local/www/cgi-bin/html_on_email3.pl

Для того, чтобы окончательно все автоматизировать, вешаем наш скрипт на CRON. Для этого в файл /etc/crontab добавляем строчку

 0 9 * * * root /usr/local/www/cgi-bin/html_on_email3.pl

и каждое утро в 9 часов читаем свежие анекдоты.

Для того, чтобы скрипт работал и в локальной сети необходимо установить соединение с Инетом и явно указать адреса прокси- и SMTP - сервера.

$ua->proxy(['http', 'ftp'], 'http://10.0.0.3:3128/');

MIME::Lite->send('smtp', "10.0.0.1", Timeout=>60);

В завершение хочу заметить, что все можно было написать и по-другому, более красиво. Но программа работает, а большего от нее и не требуется :-)

Полная версия статьи http://takiedela.narod.ru/press/lwp_mime.html
Исходник программы http://takiedela.narod.ru/press/html_on_email3.pl

Размещать статью полностью и или частично можете где угодно, только не забывайте меня упомянуть как автора ;-)

 
02.04.2003
Версия для печати Версия для печати Запомнить ссылку Запомнить ссылку
Ваша оценка:  1   2   3   4   5     

 О проектеПерепечаткаАвторамПартнерыО нас пишут
Наверх
©2003—2007. GETINFO.RU. ВСЕ ПРАВА ЗАЩИЩЕНЫ.