[Perl] обработка текста из форума

oyuriyu

На одном шахматном форуме есть конкурс прогнозов. Бывает, что за день человек 100 с лишним голосует.
Их админ, бедный, ручками результаты конкурса подсчитывает(кто сколько за турнир предсказал).
Я уже почти написал часть, которая вычисляет очки за отдельный тур и за весь турнир(но она и не сложная
но я не знаю, как выдрать из форума посты с предсказаниями. Помогите, пожалуйста.
Отдельный пост выглядит примерно так:
nickname
Karpov Kasparov 1/2
обсуждение
или nickname: бывает с двоеточием. Бывает, гады, и ник в посте не указывают. Никто мне не поможет ?
Нужно получить на выходе текстовый файл формата
nickname1
Karpov Kasparov 1/2
nickname2
Karpov Kasparov 1-0
nickname3
Karpov Kasparov 1-0
Сам форум тут находится, вот примерная страница с предсказаниями:
http://kasparovchess.crestbook.com/viewpoll.php?id=2047

uncle17

Как из самой страницы форума сделать список предсказаний?
В $input у тебя код страницы.
Дальше
my @posts = split("class=\"blockpost", $input);
my $out = "";
for my $i (1..$#posts) {
$posts[$i] =~ s/^.*?<div class=\"postmsg\">//is;
$posts[$i] =~ s/<\/div>.*$//is;
$posts[$i] =~ s/<br \/>/\n/is;
$posts[$i] =~ s/\<.*?\>//g; #на всякий случай
$posts[$i] .= "###############\n"; #это чтоб легче записи разграничивать
}

oyuriyu

А почему $input, а не @input ?
только ногами не пинайте
сначала wget страницу(ещё бы все страницы в треде пролистать автоматически... потом

#/usr/bin/perl
#use warnings;
#use strict;

my $filename = shift;
open FILE, $filename or die $!;
my @data;
#read the whole file
@data = <FILE>;

А ТУТ ЧТО ?
}

uncle17

а почему @input?
$input = get("http://kasparovchess.crestbook.com/viewpoll.php?id=2047");

oyuriyu

Undefined subroutine &main::get called at part1.pl line 4
нужно ещё какой-то пакет подключить
PS use LWP::Simple; ?

uncle17

ой, да...
use LWP::Simple;

Elina74

use LWP::Simple;

uncle17

а все страницы в треде - циклом пробегай все
http://kasparovchess.crestbook.com/viewpoll.php?id=2047&...
http://kasparovchess.crestbook.com/viewpoll.php?id=2047&...
http://kasparovchess.crestbook.com/viewpoll.php?id=2047&...
там урлы простые

oyuriyu

вот такая прога

#/usr/bin/perl
use warnings;
use strict;
use LWP::Simple;

my $input = get("http://kasparovchess.crestbook.com/viewpoll.php?id=2047");
my @posts = split("class=\"blockpost", $input);
my $out = "";
for my $i (1..$#posts) {
$posts[$i] =~ s/^.*?<div class=\"postmsg\">//is;
$posts[$i] =~ s/<\/div>.*$//is;
$posts[$i] =~ s/<br \/>/\n/is;
$posts[$i] =~ s/\<.*?\>//g; #на всякий случай
$posts[$i] .= "###############\n"; #это чтоб легче записи разграничивать
}
print $#posts;
print "\n";
print @posts;


выводит кучу всякой гадости
кстати, и с юникодом какие-то проблемы
начало её вывода выглядит так
50
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html dir="ltr">
<head>

а потом
aleksm:
<D1><E2><E8><E4><EB><E5><F0> - <C3><F0><E8><F9><F3><EA>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
1/2<C0><ED><E0><ED><E4> - <CB><E5><EA><EE>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp
; &nbsp; 1/2<CC><EE><F0><EE><E7><E5><E2><E8><F7> - <C3><E5><EB><FC><F4><E0><ED><E4>&nbsp; &nbsp; &nbsp;
0-1<CA><F0><E0><EC><ED><E8><EA> - <C0><F0><EE><ED><FF><ED>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1/2

uncle17

какой гадости? Попробуй < и > экранировать
напиши
use POSIX;
POSIX::setlocale (&POSIX::LC_CTYPE, "ru_RU.CP1251");
use locale;
ибо юникодом там не пахнет

oyuriyu

та же проблема. , что у тебя выводит этот скрипт ? У меня только гадость.
А мне нужно файл вида

nick1
karpov kasparov 0-1
nick2
karpov kasparov 1-0
nick3
karpov kasparov 1/2
nick4
karpov kasparov 1-0
...

Артефакты типа

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html dir="ltr">
<head>

мне точно не нужны.

uncle17


#/usr/bin/perl
use warnings;
use strict;
use LWP::Simple;

use POSIX;
POSIX::setlocale (&POSIX::LC_CTYPE, "ru_RU.UTF-8");
use locale;

my $input = get("http://kasparovchess.crestbook.com/viewpoll.php?id=2047");
my @posts = split("class=\"blockpost", $input);
my $out = "";

open FILE,'>/home//out.txt';

for my $i (1..4) {
$posts[$i] =~ s/^.*?<div class=\"postmsg\">//is;
$posts[$i] =~ s/<\/div>.*$//is;
$posts[$i] =~ s/<br \/>/\n/is;
$posts[$i] =~ s/&nbsp;/ /is;
$posts[$i] =~ s/\s+/ /is;
$posts[$i] =~ s/\<.*?\>//g; #на всякий случай
$posts[$i] .= "###############\n"; #это чтоб легче записи разграничивать

print FILE $posts[$i];
}
close FILE;


в итоге такое нагромождение получилось
дает на выходе файл out.txt с содержимым
 Осталось оформить неизбежное!
Crest:Свидлер - Грищук &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;1/2Ананд - Леко&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1/2Морозевич - Гельфанд&nbsp; &nbsp; &nbsp; 1-0 Крамник - Аронян&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1/2
###############
 SlavoF
Свидлер - Грищук &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;1/2Ананд - Леко&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1/2Морозевич - Гельфанд&nbsp; &nbsp; &nbsp; 0-1 Крамник - Аронян&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1-0
###############
 aleksm:
Свидлер - Грищук &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;1/2Ананд - Леко&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1/2Морозевич - Гельфанд&nbsp; &nbsp; &nbsp; 0-1Крамник - Аронян&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1/2
###############
 dcp23
Свидлер - Грищук 1-0Ананд - Леко 1/2Морозевич - Гельфанд 1-0Крамник - Аронян 1-0
###############
это для первых четырех
З.Ы. Я сам в перле не понимаю ни хрена

Bibi


#/usr/bin/perl
use warnings;
use strict;
use LWP::Simple;

my $input = get("http://kasparovchess.crestbook.com/viewpoll.php?id=2047");
my @posts = split("class=\"blockpost", $input);
my $out = "";
foreach my $post ( @posts ) {
$post =~ s/^.*?<div class=\"postmsg\">//is;
$post =~ s/<\/div>.*$//is;
$post =~ s/<br \/>/\n/is;
$post =~ s/\<.*?\>//g; #на всякий случай
$post =~ s/&nbsp;//g
$post .= "###############\n"; #это чтоб легче записи разграничивать
}
shift @posts;
print $#posts;
print "\n";
print @posts;

oyuriyu

я тоже нихрена не понимаю. что-то получше написал, теперь
поприятнее хрень выводит:
50

цНЯРЕБЮЪ KasparovChess / вЕЛОХНМЮР ЛХПЮ лЕУХЙН-2007. рСП 14. йРН Б НМКЮИМЕ? - бШАХПЮЕЛ ОЮПРХЧ ДМЪ, ДЮЕЛ ОПНЦМНГ Х НАЯСФДЮЕЛ 14-И РСП.^M
^M
^M

цНЯРЕБЮЪ KasparovChess
ьЮУЛЮРМЮЪ ЙНЛЛСМЮКЙЮ МЮ ПСЯЯЙНЛ.
###############

нЯРЮКНЯЭ НТНПЛХРЭ МЕХГАЕФМНЕ!


Crest:яБХДКЕП - цПХЫСЙ&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;1/2юМЮМД - кЕЙН&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1/2лНПНГЕБХВ - цЕКЭТЮМД&nbsp; &nbsp; &nbsp; 1-0 йПЮЛМХЙ - юПНМЪМ&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1/2
###############

aleksm:
яБХДКЕП - цПХЫСЙ&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;1/2юМЮМД - кЕЙН&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1/2лНПНГЕБХВ - цЕКЭТЮМД&nbsp; &nbsp; &nbsp; 0-1йПЮЛМХЙ - юПНМЪМ&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1/2
###############

Bibi

забыл одну строчку сначала, сейчас дописал (shift @posts;)
и в цикле тоже

oyuriyu

после перекодирования из cp1251 в utf8 получше смотрится, только эти
############### и &nbsp; &nbsp; &nbsp; &nbsp; есть.

Bibi

вообще-то там обычный cp1251. у меня, по крайней мере, именно так

uncle17

диезы я тебе специально прописал, чтоб разделять записи проще было.

Bibi

в общем, вот такой код

#/usr/bin/perl
use warnings;
use strict;
use LWP::Simple;

my $input = get("http://kasparovchess.crestbook.com/viewpoll.php?id=2047");
my @posts = split("class=\"blockpost", $input);
foreach my $post ( @posts ) {
$post =~ s/^.*?<div class=\"postmsg\">//is;
$post =~ s/<\/div>.*$//is;
$post =~ s/<br \/>/\n/gis;
$post =~ s/<.*?>//g; #на всякий случай
$post =~ s/&nbsp;//g;
$post .= "###############\n"; #это чтоб легче записи разграничивать
}
shift @posts;
print $#posts;
print "\n";
print @posts;

дает такой выход (публикую частично):

49

Осталось оформить неизбежное!

Crest:

Свидлер - Грищук 1/2
Ананд - Леко 1/2
Морозевич - Гельфанд 1-0
Крамник - Аронян 1/2
###############

SlavoF

Свидлер - Грищук 1/2
Ананд - Леко 1/2
Морозевич - Гельфанд 0-1
Крамник - Аронян 1-0
###############

aleksm:

Свидлер - Грищук 1/2
Ананд - Леко 1/2
Морозевич - Гельфанд 0-1
Крамник - Аронян 1/2
###############

dcp23

Свидлер - Грищук 1-0
Ананд - Леко 1/2
Морозевич - Гельфанд 1-0
Крамник - Аронян 1-0
###############

oyuriyu

Исправлено : да, с диезами лучше, затупил, тамже ещё посты есть и вещи типа
Крамник - Аронян --- ОНЛАЙН!
Отредактировано Кенгуру (28/09/2007 20:36:39)
, , большое спасибо ! Не добьёте прогу ? мне бы ещё желательно чтобы ники были
на отдельной строчке и по прогнозу на строчке (так и в форуме было: 1 строчка — 1 прогноз. Скрипт
это портит). Перекодировать я и сам смогу, внешнюю прогу вызову в скрипте.
Меня удивляет насколько код получился короткий. Тяжело ещё прикрутить проверку времени поста, чтобы
не постили раньше времени и nickname выдирать из кода страницы, а не в посте смотреть(а то может я
чужой ник для хохмы укажу)?

Bibi

  
#/usr/bin/perl
use warnings;
use strict;
use LWP::Simple;

my $input = get("http://kasparovchess.crestbook.com/viewpoll.php?id=2047");
my @posts = split("class=\"blockpost", $input);
my $out = "";
foreach my $post ( @posts ) {
$post =~ s/^.*?<div class=\"postmsg\">//is;
$post =~ s/<\/div>.*$//is;
$post =~ s/<br \/>/\n/gis;
$post =~ s/<.*?>//g; #на всякий случай
$post =~ s/&nbsp;//g;
$post =~ s/^[\s\t]*//g;
$post =~ s/\t+/ /g;
$post =~ s/\n+/\n/gis;
$post .= "###############\n"; #это чтоб легче записи разграничивать
}
shift @posts;
print $#posts;
print "\n";
print @posts;

oyuriyu

спасибо. Странно, что вот это на одной строке, а не на разных
Финишный рывок... ###############

там был смайлик ...
Оставить комментарий
Имя или ник:
Комментарий: