Интро
Цель — создать
Я слышал, что если нападает перфекционизм, то надо полежать, отдохнуть и это пройдет.
Подумаешь, в валидаторе ошибка…
Но если все же не проходит, то
Ставим докер и контейнер с валидатором
Раньше поставить локальный валидатор было делом муторным.
Не то, что бы сложным, а требующим времени.
С приходом докера он устанавливается за секунды.
Ставим докер:
yum install docker
После установки докера берем себе готовый образ с собранным валидатором:
docker pull magnetikonline/html5validator
Когда образ закачается, то запускаем его:
docker run -p 8080:80 -p 8888:8888 --name validator --restart=always -d magnetikonline/html5validator
И стартуем:
docker start validator
После запуска можно зайти на http://localhost:8888 и увидеть:
Локальный валидатор работает! Его можно натравить на какой-нибудь сайт.
И проверяем с командной строки:
curl 'localhost:8888?doc=http://www.w3schools.com'
И вот такой результат:
Как видно, валидатор нашел 3 ошибки.
Паучок
Теперь надо написать скрипт, который бы обошел все страницы сайта.
За основу я взял вот такой web crawler/scraper на основе Mojo.
И немного изменил:
#!/usr/bin/env perl
use 5.010;
use open qw(:locale);
use strict;
use utf8;
use warnings qw(all);
use Mojo::UserAgent;
use List::MoreUtils 'true';
use Term::ANSIColor;
# Адрес сайта для проверки
my $site_to_check = 'http://habrahabr.ru';
# Адрес локального валидатора
my $local_validator = 'http://192.168.1.217:8888';
# FIFO queue
my @urls = ( Mojo::URL->new($site_to_check) );
# User agent following up to 5 redirects
my $ua = Mojo::UserAgent->new( max_redirects => 5 );
# Track accessed URLs
my $active = 0;
my %uniq;
sub parse {
my ($tx) = @_;
# Request URL
my $url = $tx->req->url;
# Extract and enqueue URLs
for my $e ( $tx->res->dom('a[href]')->each ) {
# Validate href attribute
my $link = Mojo::URL->new( $e->{href} );
next if 'Mojo::URL' ne ref $link;
# "normalize" link
$link = $link->to_abs( $tx->req->url )->fragment(undef);
next unless $link->protocol =~ /^https?$/x;
# Don't go deeper than /a/b/c
next if @{ $link->path->parts } > 3;
# Access every link only once
next if ++$uniq{ $link->to_string } > 1;
# Don't visit other hosts
next if $link->host ne $url->host;
push @urls, $link;
my $get = $ua->get( $local_validator . "?doc=$link" )->res->body;
my @answ = split / /, $get;
my $count = true { /class="error"/ } @answ;
print color("green"), $link, color("reset");
print " Кол-во ошибок в валидаторе: ",
color("red"), "$count \n", color("reset");
}
return;
}
sub get_callback {
my ( undef, $tx ) = @_;
# Parse only OK HTML responses
$tx->res->code == 200
and $tx->res->headers->content_type =~ m{^text/html\b}ix
and parse($tx);
# Deactivate
--$active;
return;
}
Mojo::IOLoop->recurring(
0 => sub {
# Keep up to 4 parallel crawlers sharing the same user agent
for ( $active .. 4 - 1 ) {
# Dequeue or halt if there are no active crawlers anymore
return ( $active or Mojo::IOLoop->stop )
unless my $url = shift @urls;
# Fetch non-blocking just by adding
# a callback and marking as active
++$active;
$ua->get( $url => \&get_callback );
}
}
);
# Start event loop if necessary
Mojo::IOLoop->start unless Mojo::IOLoop->is_running;
Ссылка на гитхаб
Результат работы:
Комментарии (7)
kabal375
01.09.2015 11:05Это наверное полезная статья, так что минусовать рука не поднимается, но что она делает в хабе «виртуализация»? Просто из-за наличия докера в процессе подготовки? Эдак можно добавлять сюда что угодно, просто по факту того, что что угодно можно запускать в виртуальной среде.
Я просто интересуюсь технологиями виртуализации, но не интересуюсь веб-программировании и уже не знаю как мне отфильтровать ленту, чтобы не видеть статьи о веб-разработке от людей, открывших для себя VMware Workstation.pcdesign
01.09.2015 12:12Хаб «виртуализация» убрал.
Я просто в восторге от докера, наверное поэтому воткнул в «Виртуализацию» :)
kloppspb
>Раньше поставить локальный валидатор было делом муторным.
>Не то, что бы сложным, а требующим времени.
Так эти ужасы по ссылке скрыты внутри одного HTML::Tidy, разве нет?
pcdesign
Немного разные оперы.
kloppspb
И то, и то ведь — надстройка над tidyp. Но первом случае оно ещё и как веб-сервис работает, а в случае HTML::Tidy только автономно (что далеко не минус), зато ставится намного проще. В чём принципиальная разница?
P.S. А вообще, для нелокальных сайтов/страниц можно и напрямую обращаться к validator.w3.org/check?uri=… :)
pcdesign
— Это на счет HTML::Tidy
HTML Tidy is a great utility for pretty-printing your HTML, and it may
clean it up a bit, though I wouldn't trust it to do too much of that.
It's not a validator, though. It's a linter. There is, orbiting
somewhere inside the W3C solar system, some validator software written
by one of the W3C guys.
— А на счет обращений к validator.w3, если надо 100500 страниц проверить, то лучше к локальному валидатору обращаться.
И быстрее и не забанят.
kloppspb
Я про валидатор по первой ссылке, который «Building the W3C Markup Validation Service from source». Чем он отличается от HTML::Tidy, если внутри себя использует ту же tidyp?
А вообще, можно просто сравнить результаты во всех трёх случаях :)