Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Perl: Общие вопросы > качаем страницу


Автор: Axe79 21.7.2009, 01:10
Нужен совет.
Задача обычная скачать страничку (просто текст)
Код

#!/usr/bin/perl

use LWP::UserAgent;
my $path="http://www.vashmagazin.ua/cat/catalog/?rub=128&subrub=1";
my $browser = LWP::UserAgent->new();
my $response = $browser->get($path,
    'User-Agent' => 'Mozilla/5.0 (Windows; U; Windows NT 5.1; ru; rv:1.9.0.8) Gecko/2009032609 Firefox/3.0.8',
    'Accept' => 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
    'Accept-Charset' => 'windows-1251,utf-8;q=0.7,*;q=0.7',
    'Accept-Language' => 'ru,en-us;q=0.7,en;q=0.3',
);
$www=$response->content;
use Encode qw(encode decode);
$contents = Encode::encode('utf8', Encode::decode('Windows1251', $www));

open(F, ">/home/axe/Desktop/ddd")||die "$!";
print  $contents;
print F $contents;
close(F);


И во когда победа вроде бы близка и стоит открыть файл и пропустить через фильтры 
... В файле привет от китайского посла.
Кодировки... Какая у меня? в какую конвертировать...? В общем в данном случае бесплодие методом тыка не лечится((( Вот.

Сижу под линухами Alt.
P.S. при чём что интересно в консоли всё ок а файл в иероглифах.
И вообще может есть толее цивилизованый метод получить чистый текст...
Заранее спасибо.

Автор: Itsys 21.7.2009, 07:05
А ты уверен, что исходная страница в "Windows1251", ты б сначала использовал find_encoding....

Автор: Axe79 21.7.2009, 08:58
не уверен...

если не тяжело приведите пример использования...

Просто в перловском ООП я новичок и немного путаюсь с синтаксисом(((

Добавлено @ 09:06
Вроде как  на CPAN-е

Encode::Alias ?

[$obj =] find_encoding(ENCODING)

$obj---это опредиляемый текст?
ENCODING--- это кодировка...?

в общем в таком формате не работает
Код

$My_Text = find_encoding($contents);
print  $contents;



Автор: Pfailed 21.7.2009, 09:29
Axe79, код у вас в первом посте вполне рабочий. Это подтверждает то, что при выводе на консоль текст читаем. Проблема у вас с текстовым редактором, где вы затем пытаетесь открыть сохраненный файл. Этот редактор либо не поддерживает utf8, либо по умолчанию открывает текст в неверной кодировке. Что это за редактор?

Автор: Axe79 21.7.2009, 09:41
автоматически открывает в Konqeror
Закидываю в мозиллу тоже самое
Опен офис Аналогично

только если в простом kwrite то никаких проблем с кодировкой

но у меня задача загрузив и сохранив страничку в файле открыть и пропустить через фильтры

боюсь что я не туда забрёл...

Потому что от тегов шаблонов и линков простым открытием не избавиться...
то-есть если-б скрипт выдавал чистый текст я его наверное даже не сохранял а пускал в обработку

Простите за сумбурность

Добавлено через 7 минут и 59 секунд
но на будущее универсальный определитель исходной кодировки не помешал бы... smile  smile  

Автор: Pfailed 21.7.2009, 09:58
Ну ясное дело что в браузере страница открывается в неверной кодировке, потому как в коде страницы не указан charset. Вам нужно удалить все теги и оставить только текст? Посмотрите в сторону модуля HTML::FormatText. Если вам нужно извлечь какой-то конкретный текст страницы можно будет обойтись и простым регулярным выражением.

Автор: Axe79 21.7.2009, 21:28
а есть какая-то основоположная разница между использованием регулярных выражений для очистки от гипертекстовой разметки?

и использованием модуля HTML::FormatText

 я например почти полностью обошёлся такими шаблонами:
Код


if(/[а-я]/){
s/>|<|[A-z];|"|=|&|[A-z]//g;
s/тел.\/:/тел.:/g;
s/(\d{2,5})\//$1/g;
s/^$|^\n$//g;
$,="\n";
print ;}


может я и не прав ... Посоветуйте.

Добавлено через 2 минуты и 27 секунд
просто в шаблонах немного разбираюсь а с HTML::FormatText нет.
да и внятных примеров чего-то не нашёл.

Автор: burakov 22.7.2009, 13:19
Добрый день,
работаю под Windows...

так что немного у меня не так как у Вас, 
код который дал Axe79 действительно что то делает, но Encode как то не так срабатывает....
Я его переписал на свой манер (именно там где используется Encode) и у меня под windows все нормально заработало.....
может мой код поможет?

Код

use strict; 
use warnings;
use LWP::UserAgent;

my $path="http://www.rambler.ru/index.html";
my $browser = LWP::UserAgent->new();
my $response = $browser->get($path,
    'User-Agent' => 'Mozilla/5.0 (Windows; U; Windows NT 5.1; ru; rv:1.9.0.8) Gecko/2009032609 Firefox/3.0.8',
    'Accept' => 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
    'Accept-Charset' => 'windows-1251,utf-8;q=0.7,*;q=0.7',
    'Accept-Language' => 'ru,en-us;q=0.7,en;q=0.3',
);
my $www = $response->content;

use Encode qw(encode decode);
my $contents = encode ('cp1251', decode ('utf8', $www));
open (FILE, ">1.txt") or die; 
print FILE $contents;
close (FILE); 

Автор: yorm 22.7.2009, 17:24
Цитата

.. В файле привет от китайского посла.


похоже, что кодировка правильная (utf8) но без флага. Распространенная проблема. Попробуй включить _utf8_on() - в строку добавится флаг.

Если правильно понял, проблема узнать, в какой кодировке действительно отсылается страница? Я смотрю Firefox -> View -> Character Encoding, обычно так показывает правильно.
А вообще, для конвертации можно использовать Text::Iconv, конвертирует на ура (но проблему с флагом не решает)

Автор: Axe79 28.7.2009, 18:09
Ещё один нюанс.
Язык украинский и почему то вместо некоторых букв идут непечатаемые символы.

используется такая кодировка

Код

$contents = encode('utf8', decode('cp1251', $response->content));


вот результаты:

рстві� із
ПопитБIЗНЕС-� ЕКЛАМАГ

короче  "Р" глючит и "Э"

Автор: Pfailed 28.7.2009, 18:13
Цитата(Axe79 @  28.7.2009,  18:09 Найти цитируемый пост)
Ещё один нюанс.

Ссылку на страничку с этими символами будьте добры.

Автор: Axe79 28.7.2009, 18:30
но проблем
http://vashmagazin.ua/cat/catalog/?rub=128&subrub=1&item_price1=&item_price2=&page=1

Автор: Pfailed 28.7.2009, 18:49
Цитата(Axe79 @  28.7.2009,  18:30 Найти цитируемый пост)
http://vashmagazin.ua/cat/catalog/?rub=128...ce2=&page=1

Что то я не обнаружил тут ни символа "Р", ни символа "Э".
http://www.vashmagazin.ua/cat/catalog/?rub=106&subrub=4 есть "Р", но он как и положено после сохранения отображается символом "Р". Проверено на следующем однострочнике:
Код

perl -MEncode -MLWP::UserAgent -e 'print decode("cp1251", LWP::UserAgent->new->get("http://www.vashmagazin.ua/cat/catalog/?rub=106&subrub=4")->content)' > dump.html

Автор: mrrico 28.7.2009, 19:06
Имхо,
utf не совсем обычный текст. Можно довольно часто дать print на utf текст и скрипт обломится. wide character.

Думаю, решение было в том, чтобы дать на текстовый файлхэндл вот такую штуку:

Код

open(F, ">/home/axe/Desktop/ddd")||die "$!";
 binmode F;
print  $contents;
print F $contents;
close(F);


Тогда бы и utf в файл нормально записался.

Автор: chorny 29.7.2009, 03:13
Кстати сайт правильно пишет в заголовках: "Content-Type: text/html; charset=windows-1251"

Вот так у меня правильно отображается страница в Firefox
Код

#!/usr/bin/perl

use strict;use warnings;
use LWP::UserAgent;
my $path="http://vashmagazin.ua/cat/catalog/?rub=128&subrub=1&item_price1=&item_price2=&page=1";
my $browser = LWP::UserAgent->new();
my $response = $browser->get($path,
    'User-Agent' => 'Mozilla/5.0 (Windows; U; Windows NT 5.1; ru; rv:1.9.0.8) Gecko/2009032609 Firefox/3.0.8',
    'Accept' => 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
    'Accept-Charset' => 'windows-1251,utf-8;q=0.7,*;q=0.7',
    'Accept-Language' => 'ru,en-us;q=0.7,en;q=0.3',
);
my $www=$response->content;
use Encode qw(encode decode);
my $contents = Encode::encode('utf8', Encode::decode('Windows1251', $www));
$contents=~s#<head>#<head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />#i;
open(my $f, ">","ddd.html")||die "$!";
print $f $contents;
close($f);


Автор: Axe79 30.7.2009, 16:09
тут походу ошибка в другом

после скачки всё нормально:


<option value="100" >НЕРУХОМIСТЬ-Житло в новобудовах</option><option value="102" >НЕРУХОМIСТЬ-Однокімнатні квартири</option><option value="104" >НЕРУХОМIСТЬ-Двокімнатні квартири</option><option value="106" >НЕРУХОМIСТЬ-Трикімнатні квартири</option><option value="108" >НЕРУХОМIСТЬ-Чотирикімнатні квартири</option><option value="110" >НЕРУХОМIСТЬ-Багатокімнатні квартири</option><option value="112" >НЕРУХОМIСТЬ-Кімнати в місті та передмісті</option><option value="114" >НЕРУХОМIСТЬ-Квартири та кімнати в області</option>

А вот после обработки HTML::FormatText имеем:

НЕ� УХОМIСТЬЖитло в новобудовахНезавершенеЗдане після 2002 р.Однокімнатні квартириГалицький р-нФранкiвський р-нЛичакiвський р-нШевченкiвський р-нЗалiзничний р-нСихiвський р-нДвокімнатні квартириГалицький р-нФранкiвський р-нЛичакiвський р-нШевченкiвський р-нЗалiзничний р-нСихiвськийр-нЛичакiвський р-нШевченкiвський р-нЗалiзничний р-нСихiвський р-нКімнати в місті та передмістіГалицький р-нФранкiвський р-нЛичакiвський р-нШевченкiвський р-нЗалiзничний р-нСихiвський р-нКвартири та кімнати в областіПропозиціяКвартири та кімнати за межами областіПропозиціяКвартири
та кімнати. ПопитПопит в містіПопит за межами містаОбмін житлаЗ'їзд� оз'їзд� івноціннийЗ більшої

вот код:
Код

#!/usr/bin/perl 
use HTML::FormatText;

 require HTML::TreeBuilder;
 $tree = HTML::TreeBuilder->new->parse_file("/home/axe/Desktop/syrOr.txt") || die "$!";

 require HTML::FormatText;
 $formatter = HTML::FormatText->new(leftmargin => 0, rightmargin => 500);
 $tmps=$formatter->format($tree);

@data=split("\n", $tmps);
open(F, ">/home/axe/Desktop/magOr.txt") || die "$!";
print  F $tmps;
close(F);



Добавлено @ 16:13
к стати если можно б было сразу закинуть данные в

Код

 require HTML::FormatText;
 $formatter = HTML::FormatText->new(leftmargin => 0, rightmargin => 500);
 $tmps=$formatter->format($tree);


А то тут просит через файл 
Код

 require HTML::TreeBuilder;
 $tree = HTML::TreeBuilder->new->parse_file("/home/axe/Desktop/syrOr.txt") || die "$!";


по уму  красивее было б в одном скрипте скачать и отчистить от гипертекстовой разметки
без промежуточного баловства с файлами и дескрипторами

Добавлено @ 16:15
а то выходит как то не эстетично...
в одном качаем в другом чистим

Добавлено @ 16:17
для полноты ситуации сейчас скрипт для скачки выглядит так:
Код

#!/usr/bin/perl
use Encode qw(encode decode);
use LWP::UserAgent;
use POSIX;

print "Insert data code\npres 'a' for automatic insert\n";
chomp($dat=<STDIN>);
if ($dat eq 'a' or $dat eq 'A'){$dat=(strftime "%d%m", localtime);}

open(BAS, "/home/axe/Desktop/wmag/orenda/magOrBAS") || die "$!";
@path=<BAS>;
close(BAS);

open(DATA, ">/home/axe/Desktop/wmag/orenda/syrOr$dat.txt") || die "$!";
$starttime=(strftime "%H%M%S", localtime);

for (@path){
$razd++;
$page=1;
chomp $_;
s/1$//;
print DATA "\nrazzi", $razd x 3, "\n\n";
while ($page) {
my $path="$_$page";
my $browser = LWP::UserAgent->new();
my $response = $browser->get($path,
    'User-Agent' => 'Mozilla/5.0 (Windows; U; Windows NT 5.1; ru; rv:1.9.0.8) Gecko/2009032609 Firefox/3.0.8',
    'Accept' => 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
    'Accept-Charset' => 'windows-1251,utf-8;q=0.7,*;q=0.7',
    'Accept-Language' => 'ru,en-us;q=0.7,en;q=0.3',
);
$contents = encode('utf8', decode('cp1251', $response->content));
print DATA "\n\n\nRAZDELL\n$_$page\n", $contents;
@data=split("\n", $contents);

for $dd (@data){
push(@alldata, $dd);
if($dd=~/<strong>тел.<\/strong>:.*&nbsp;/){$p++;}}
print  "\n", (strftime "%H%M%S", localtime), " Contacts $p $_$page compliting\n";
$page++;
if ($p==0){$page=0;}
$p=0;
}
}
print DATA "\n\nAll strings is $#alldata\n";
print "Start in $starttime\nAll strings is $#alldata\n";
close(DATA);


Добавлено @ 16:22
цикл ваял часа в 3 ночи. так что громко не смейтесь ...
главное что работает smile 

Автор: Pfailed 30.7.2009, 18:12
Цитата(Axe79 @  30.7.2009,  16:09 Найти цитируемый пост)
по уму  красивее было б в одном скрипте скачать и отчистить от гипертекстовой разметкибез промежуточного баловства с файлами и дескрипторами

Естественно можно: HTML::TreeBuilder->new->parse_content($data);

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)