CSS3文档类型嗅探,特别是Mojo::DOM



我可以使用Mojo::DOM和它的CSS3选择器来找出HTML文档的DOCTYPE ?与我的另一个问题相关,我应该如何处理HTML META标记与Mojo::UserAgent?当我想要设置文档的字符集时,我需要知道要查看什么,而doctype嗅探似乎是一种方法。当文档设置覆盖服务器设置(或非设置)时,HTML和HTML 5对HTML中的字符集有不同的元标记。

完成任务没有问题,因为我可以抓取原始响应并使用正则表达式来查看DOCTYPE。由于浏览器dom似乎能够获得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'}
                                  ],

我怎么得到它呢?

确定HTML5文档的编码是非常复杂的。恐怕Mojo::DOM只是一个片段解析器,因此我们认为编码嗅探算法的完整实现将超出范围。值得庆幸的是,大多数网页都是UTF-8编码的,我想这就是为什么这个问题不经常出现的原因。

我仍然认为有希望有一个更好的方法来做到这一点,但也许我把太多的责任放在Mojo::UserAgent上。我可以构建一个事务并将finish事件添加到响应中。在这种情况下,我使用正则表达式嗅探内容,并添加具有doc类型的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值,并根据这些值决定如何处理内容。

最新更新