gpt4 book ai didi

Perl HTML::Tokeparser 获取标签之间的原始 html

转载 作者:行者123 更新时间:2023-12-02 04:41:20 25 4
gpt4 key购买 nike

我正在使用 TokeParser 提取标签内容。

...
$text = $p->get_text("/td") ;
...

通常它会返回清理过的文本。我想要的是返回 td/td 之间的所有内容,但包括所有其他 html 元素。怎么做。

我正在使用 this tutorial 中的示例.谢谢

在例子中,

my( $tag, $attr, $attrseq, $rawtxt) = @{ $token };

我相信 $rawtxt 有一些技巧。

最佳答案

HTML::TokeParser 没有内置功能来执行此操作。但是,可以通过查看 <td> 之间的每个标记来实现。 s 单独。

#!/usr/bin/perl
use strictures;
use HTML::TokeParser;
use 5.012;

# dispatch table with subs to handle the different types of tokens
my %dispatch = (
S => sub { $_[0]->[4] }, # Start tag
E => sub { $_[0]->[2] }, # End tag
T => sub { $_[0]->[1] }, # Text
C => sub { $_[0]->[1] }, # Comment
D => sub { $_[0]->[1] }, # Declaration
PI => sub { $_[0]->[2] }, # Process Instruction
);

# create the parser
my $p = HTML::TokeParser->new( \*DATA ) or die "Can't open: $!";

# fetch all the <td>s
TD: while ( $p->get_tag('td') ) {
# go through all tokens ...
while ( my $token = $p->get_token ) {
# ... but stop at the end of the current <td>
next TD if ( $token->[0] eq 'E' && $token->[1] eq 'td' );
# call the sub corresponding to the current type of token
print $dispatch{$token->[0]}->($token);
}
} continue {
# each time next TD is called, print a newline
print "\n";
}

__DATA__
<html><body><table>
<tr>
<td><strong>foo</strong></td>
<td><em>bar</em></td>
<td><font size="10"><font color="#FF0000">frobnication</font></font>
<p>Lorem ipsum dolor set amet fooofooo foo.</p></td>
</tr></table></body></html>

此程序将解析 __DATA__ 中的 HTML 文档部分并打印所有内容,包括 <td> 之间的 HTML和 </td> .每 <td> 打印一行.让我们逐步了解它。

  • 看完documentation ,我了解到 HTML::TokeParser 中的每个标记都有一个与之关联的类型。有六种类型:S , E , T , C , DPI .文档说:

    This method will return the next token found in the HTML document, or undef at the end of the document. The token is returned as an array reference. The first element of the array will be a string denoting the type of this token: "S" for start tag, "E" for end tag, "T" for text, "C" for comment, "D" for declaration, and "PI" for process instructions. The rest of the token array depend on the type like this:

    ["S",  $tag, $attr, $attrseq, $text]
    ["E", $tag, $text]
    ["T", $text, $is_data]
    ["C", $text]
    ["D", $text]
    ["PI", $token0, $text]
  • 我们想要访问 $text存储在这些 token 中,因为没有其他方法可以获取看起来像 HTML 标签的东西。因此我创建了一个 dispatch table%dispatch 中处理它们.它存储了一堆稍后调用的代码引用。

  • 我们阅读了来自 __DATA__ 的文档, 这对于这个例子来说很方便。
  • 首先,我们需要获取 <td>通过使用 get_tag方法。 @nrathaus 的评论向我指出了这一点。它会将解析器移动到打开后的下一个标记 <td> .我们不关心什么get_tag返回,因为我们只想要 <td> 之后的标记.
  • 我们使用方法 get_token获取下一个 token 并用它做一些事情:

    • 但我们只想这样做,直到找到相应的结束 </td> .如果我们看到了,我们 next外层while标记为 TD 的循环.
    • 此时, continue block被调用并打印换行符。
    • 如果我们没有走到最后,奇迹就会发生:调度表;正如我们之前看到的, token 数组 ref 中的第一个元素包含类型。 %dispatch 中的每种类型都有一个代码引用.我们调用它并传递完整的数组 ref $token通过去 $coderef->(@args) .我们在当前行打印结果。

      这将产生像 <strong> 这样的东西, foo , </strong>等等。

请注意,这仅适用于一张 table 。如果表中有表(类似于 <td> ... <td></td> ... </td> ),这将中断。您必须调整它以记住它有多少层深。


另一种方法是使用 miyagawa 的优秀 Web::Scraper .这样,我们的代码就少了很多:

#!/usr/bin/perl
use strictures;
use Web::Scraper;
use 5.012;

my $s = scraper {
process "td", "foo[]" => 'HTML'; # grab the raw HTML for all <td>s
result 'foo'; # return the array foo where the raw HTML is stored
};

my $html = do { local $/ = undef; <DATA> }; # read HTML from __DATA__
my $res = $s->scrape( $html ); # scrape

say for @$res; # print each line of HTML

这种方法还可以像魅力一样处理多维表。

关于Perl HTML::Tokeparser 获取标签之间的原始 html,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20785388/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com