2015-09-09 6 views
3

Я могу использовать Mojo::DOM и его селектора CSS3 для определения DOCTYPE документа HTML? В связи с моим другим вопросом, How should I process HTML META tags with Mojo::UserAgent?, где я хочу установить набор символов для документа, мне нужно знать, что посмотреть, и doctype sniffing, похоже, это способ сделать. HTML и HTML 5 имеют разные метатеги для кодировок в HTML, когда параметр документа переопределяет настройку сервера (или не устанавливает).Doctype sniffing с CSS3, и особенно с Mojo :: DOM

У меня нет проблем с выполнением задачи, так как я могу получить сырой ответ и играть с регулярными выражениями, чтобы посмотреть DOCTYPE. Since the browser DOMs seem to be able to get the DOCTYPE, я заражен идеей, что я должен ее получить. Однако отсутствие примеров приводит меня к мысли, что никто не делает это так, как я думаю, я должен это делать.

Я пробовал много глупых способы, но мой CSS кунг-фу является слабым:

use v5.20; 

use feature qw(signatures); 
no warnings qw(experimental::signatures); 

use Mojo::DOM; 

my $html = do { local $/; <DATA> }; 

my $dom = Mojo::DOM->new($html); 

say "<title> is => ", $dom->find('head title')->map('text')->each; 

say "Doctype with find is => ", $dom->find('!doctype')->map('text')->each; 

say "Doctype with nodes is => ", $dom->[0]; 

__DATA__ 

<!DOCTYPE html> 
<head> 
<title>This is a title</title> 
</head> 
<body> 
<h1>Level 1</h1> 
</body> 
</html> 

Когда я дамп $dom объекта, я вижу DOCTYPE в дереве:

$VAR1 = bless(do{\(my $o = bless({ 
         'tree' => [ 
            'root', 
            [ 
            'text', 
            '', 
            ${$VAR1}->{'tree'} 
            ], 
            [ 
            'doctype', 
            ' html', 
            ${$VAR1}->{'tree'} 
            ], 

Теперь, как сделать Я понял?

+0

Не похоже на встроенный способ сделать это, так как doctype хранится на верхнем уровне дерева. Лучшее, что я мог придумать, это сделать: 'my% ugly_tree = @ {$ dom-> root-> tree}; my ($ doctype) = $ ugly_tree {doctype}; 'Но это может быть хрупким. – xxfelixxx

+1

Тип doctype - это еще один узел, и вы можете использовать такие методы, как [child_nodes] (http://mojolicio.us/perldoc/Mojo/DOM#child_nodes), чтобы найти их. –

ответ

1

Я все еще думаю, что есть надежда на лучший способ сделать это, но, возможно, я возлагаю слишком большую ответственность на Mojo::UserAgent. Я могу построить транзакцию и добавить ответ finish. В этом случае я обнюхаю содержимое регулярным выражением и добавляю заголовок X- с типом документа. Я мог бы передать данные в какой-то другим способом, но это не главное (по-прежнему принимать предложения, хотя!)

use v5.14; 

use Mojo::UserAgent; 

@ARGV = qw(http://blogs.perl.org); 

my $ua = Mojo::UserAgent->new; 

my $tx = $ua->build_tx(GET => $ARGV[0]); 
$tx->res->on(finish => sub { 
    my $res = shift; 
    my($doctype) = $res->body =~ m/\A \s* (<!DOCTYPE.*?>)/isx; 
    if($doctype) { 
     say "Found doctype => $doctype"; 
     $res->headers->header('X-doctype', $doctype); 
     } 
    }); 
$tx = $ua->start($tx); 

say "-----Headers-----"; 
say $tx->res->headers->to_string =~ s/\R+/\n/rg; 

Вот результат:

Found doctype => <!DOCTYPE html> 
-----Headers----- 
Connection: Keep-Alive 
Server: Apache/2.2.12 (Ubuntu) 
Content-Type: text/html 
Content-Length: 20624 
Accept-Ranges: bytes 
X-doctype: <!DOCTYPE html> 
Last-Modified: Wed, 16 Sep 2015 13:08:26 GMT 
ETag: "26d42e8-5090-51fdcfe768680" 
Date: Wed, 16 Sep 2015 13:40:02 GMT 
Keep-Alive: timeout=15, max=100 
Vary: Accept-Encoding 

Теперь я должен думать о разных вещах, в проанализируйте значения DOCTYPE и решите на основе того, что делать с контентом.

2

Определение кодировки документа HTML5 очень complex. Я боюсь, что Mojo::DOM является только парсером фрагментов, и поэтому мы решили, что полная реализация алгоритма кодирования кодирования окажется вне области видимости. Большая часть Интернета, к счастью, кодируется UTF-8, и я думаю, поэтому этот вопрос не возникает очень часто.

+0

Моя проблема немного проще: я только хочу определить, что они говорят, что набор символов даже если он ошибочен. Существует определенный неправильно настроенный веб-сервер, который мотивировал эту проблему. :) –