perl - 使用 Mojolicious 用户代理解析 HTML

标签 perl mojolicious

我有类似这样的html

 <h1>My heading</h1>

 <p class="class1">
 <strong>SOMETHING</strong> INTERESTING (maybe not).
 </p>

 <div class="mydiv">
 <p class="class2">
 <a href="http://www.link.com">interesting link</a> </p>

 <h2>Some other heading</h2>

h1 和 h2 之间的内容不同——我知道我可以在 Mojo::Dom 中使用 css 选择器来选择 h1 或 h2 的内容,或者 p 标签——但是如何选择 h1 和 h2 之间的所有内容?或者更一般地说,任意两组给定标签之间的所有内容?

最佳答案

这很简单。您可以在 Mojo::Collection 中选择所有有趣的元素对象(例如 Mojo::DOMchildren 方法所做的)并在迭代该集合时执行某种状态机之类的匹配。

可能是最神奇的方法

是使用Perl的range operator ..在标量上下文中:

In scalar context, ".." returns a boolean value. The operator is bistable, like a flip-flop, and emulates the line-range (comma) operator of sed, awk, and various editors. Each ".." operator maintains its own boolean state, even across calls to a subroutine that contains it. It is false as long as its left operand is false. Once the left operand is true, the range operator stays true until the right operand is true, AFTER which the range operator becomes false again. It doesn't become false till the next time the range operator is evaluated.

这是一个

简单示例

#!/usr/bin/env perl

use strict;
use warnings;
use feature 'say';
use Mojo::DOM;

# slurp all DATA lines
my $dom = Mojo::DOM->new(do { local $/; <DATA> });

# select all children of <div id="yay"> into a Mojo::Collection
my $yay = $dom->at('#yay')->children;

# select interesting ('..' operator in scalar context: flip-flop)
my $interesting = $yay->grep(sub { my $e = shift;
    $e->type eq 'h1' .. $e->type eq 'h2';
});

say $interesting->join("\n");

__DATA__
<div id="yay">
    <span>This isn't interesting</span>
    <h1>INTERESTING STARTS HERE</h1>
    <strong>SOMETHING INTERESTING</strong>
    <span>INTERESTING TOO</span>
    <h2>END OF INTERESTING</h2>
    <span>This isn't interesting</span>
</div>

输出

<h1>INTERESTING STARTS HERE</h1>
<strong>SOMETHING INTERESTING</strong>
<span>INTERESTING TOO</span>
<h2>END OF INTERESTING</h2>

说明

所以我正在使用 Mojo::Collection 的 grep过滤集合对象 $yay。因为它寻找真相,所以它为给定函数的返回值创建了一个标量上下文,所以 .. 操作符就像一个触发器。它在第一次看到 h1 元素后变为真,在第一次看到 h2 元素后变为假,所以你得到标题中所有 between 的行包括他们自己。

由于我认为您了解一些 Perl,并且您可以将任意测试与 .. 一起使用,我希望这有助于解决您的问题!

关于perl - 使用 Mojolicious 用户代理解析 HTML,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13809845/

相关文章:

perl - 如何使用变量执行 Perl qx 函数

perl - 从字符串中删除引号

perl - 如何写出或读入 Perl 散列的数组?

perl - 打包和部署 mojolicious 应用程序的最佳方式

perl - 在 Mojolicious Controller 单元测试中将文件作为参数传递

perl - 如何强制 Mojolicious 向客户发送响应?

PerlTk 标签 - 同一小部件​​中的不同颜色文本

arrays - Perl:将数据从哈希转储到 Excel 中

perl - 我们如何对 Mojolicious Controller 进行单元测试?

perl - 如何调试用于从客户端上传文件的服务器端脚本(在此示例中为 curl)?