Perl 是一种强大的文本处理语言,特别适合从 HTML 中提取特定文本内容。HTML 解析是指从 HTML 文档中提取结构化数据或特定文本片段的过程。
对于简单的 HTML 解析任务,可以使用 Perl 的正则表达式:
use strict;
use warnings;
my $html = '<html><body><h1>Title</h1><p>Content</p></body></html>';
if ($html =~ /<h1>(.*?)<\/h1>/) {
print "Found title: $1\n";
}
优点:简单快速,适合简单任务 缺点:对复杂或格式不规范的 HTML 不可靠
use HTML::Parser;
my $title;
my $p = HTML::Parser->new(
start_h => [sub {
my ($tagname, $attr) = @_;
if ($tagname eq 'h1') {
$title = '';
}
}, "tagname, attr"],
text_h => [sub {
$title .= $_[0] if defined $title;
}, "dtext"],
end_h => [sub {
my $tagname = shift;
if ($tagname eq 'h1' && defined $title) {
print "Title: $title\n";
undef $title;
}
}, "tagname"],
);
$p->parse_file('example.html');
更高级的 DOM 式解析:
use HTML::TreeBuilder;
my $tree = HTML::TreeBuilder->new;
$tree->parse_file('example.html');
# 查找所有<h1>标签
my @h1s = $tree->look_down('_tag', 'h1');
foreach my $h1 (@h1s) {
print "Title: ", $h1->as_text, "\n";
}
$tree->delete; # 清理内存
use Mojo::DOM;
my $dom = Mojo::DOM->new(do { local $/; open my $fh, '<', 'example.html'; <$fh> });
# 查找所有链接
$dom->find('a')->each(sub {
print "Link: ", $_->text, " => ", $_->attr('href'), "\n";
});
原因:HTML 不规范或有嵌套标签 解决:使用更健壮的解析器如 HTML::TreeBuilder 或 Mojo::DOM
原因:大文件解析时 DOM 占用内存 解决:使用流式解析器 HTML::Parser 或分块处理
原因:HTML 编码与 Perl 处理编码不一致 解决:明确指定编码
open my $fh, '<:encoding(UTF-8)', 'example.html' or die $!;