【发布时间】:2011-01-14 07:04:22
【问题描述】:
我希望能够从 HTML/XHTML 文档中提取所有纯文本并分析/修改,然后在需要时进行替换。我可以使用HTML::Parser 执行此操作还是应该使用XML::Parser?
有没有人知道的好的演示?
【问题讨论】:
我希望能够从 HTML/XHTML 文档中提取所有纯文本并分析/修改,然后在需要时进行替换。我可以使用HTML::Parser 执行此操作还是应该使用XML::Parser?
有没有人知道的好的演示?
【问题讨论】:
HTML::Parser 的方法基于令牌和回调。当您希望提取或更改数据的上下文具有特别复杂的条件时,我发现它非常方便。
否则我更喜欢基于树的方法。 HTML::TreeBuilder::XPath(最终基于 HTML::Parser)允许您使用 XPath 查找节点。它返回HTML::Elements。文档有点稀缺(嗯,分布在几个模块上)。但仍然是挖掘 HTML 的快速方法。
如果您处理纯 XML,XML::Twig 是一个出色的解析器:非常好的内存管理,允许结合树和流方法。而且文档非常好。
【讨论】:
假设在某人的 StackOverflow 用户页面中,您想用 Perl 替换所有 PERL 实例。你可以这样做
#! /usr/bin/perl
use warnings;
use strict;
use HTML::Parser;
use LWP::Simple;
my $html = get "http://stackoverflow.com/users/201469/phil-jackson";
die "$0: get failed" unless defined $html;
sub replace_text {
my($skipped,$markup) = @_;
$skipped =~ s/\bPERL\b/Perl/g;
print $skipped, $markup;
}
my $p = HTML::Parser->new(
api_version => 3,
marked_sections => 1,
case_sensitive => 1,
unbroken_text => 1,
xml_mode => 1,
start_h => [ \&replace_text => "skipped_text, text" ],
end_h => [ \&replace_text => "skipped_text, text" ],
);
# your page may use a different encoding
binmode STDOUT, ":utf8" or die "$0: binmode: $!";
$p->parse($html);
输出是我们所期望的:
$ wget -O phil-jackson.html http://stackoverflow.com/users/201469
$ ./replace-text >out.html
$ diff -ub phil-jackson.html out.html
--- 菲尔杰克逊.html
+++ out.html
@@ -327,7 +327,7 @@
珀尔:
-#$linkTrue = … ">比较 PERL md5() 和 PHP md5()
+#$linkTrue = … ">比较 Perl md5() 和 PHP md5()
【讨论】:
您还应该查看Web::Scraper。
我发现这个模块比 HTML::Parser 模块更容易,但如果您熟悉 XPath,它会有所帮助。
根据实际页面,HTML 的解析是非常不可预测的——它就像 pdf 显示而不是面向数据的。
【讨论】:
您应该使用哪个模块取决于您要执行的操作。对于初学者,HTML::Parser 提供了很好的示例,其中还包括一个从 HTML 文档中提取纯文本的脚本。
不要尝试使用 XML 解析器来解析 HTML 文档:您会发现自己陷入了一个痛苦的世界,因为许多有效的 HTML 结构都不是有效的 XML。
不要尝试使用 HTML 解析器来解析 XML 文档:您将失去 XML 文档在被解析之前格式正确这一更严格要求的所有优势。
【讨论】: