我可以使用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
值,并根据这些值决定如何处理内容。