繁体   English   中英

如何在html树中的节点上移并提取链接?

How to move up a node in html tree and extract the link?

提示:本站收集StackOverFlow近2千万问答,支持中英文搜索,鼠标放在语句上弹窗显示对应的参考中文或英文, 本站还提供   中文繁体   英文版本   中英对照 版本,有任何建议请联系yoyou2525@163.com。

我知道我的问题标题不是描述性的,但让我在这里解释。

我正在尝试使用HTML :: TreeBuilder解析给定的html文档 现在在此html文档中,将根据用户提供的值来验证值5,1,ABC,DEF ,如果验证成功,则必须提取href链接。

所以,我的代码是:

my @tag = $tree->look_down( _tag => 'tr', class => qr{\bepeven\scompleted\b} );
for (@tag) {

    query_element($_);
}

sub query_element {

    my @td_tag = $_[0]->look_down( _tag => 'td' );

    my $num1 = shift @td_tag; #Get the first td tag
    my $num2 = shift @td_tag; # Get the second td tag


    #Making sure first/second td tag has numeric value
    $num1 = $1 if $num1->as_text =~ m!(\d+)! or die "no match found";
    $num2 = $1 if $num2->as_text =~ m!(\d+)! or die "no match found";


    #Validating that above value's match the user provided value 5 and 1.
    if ( $num1 eq '5' && $num2 eq '1' ) { 
        say "hurray..!!";

        #Iterating over rest of the td tag to make sure we get the right link from it.
        for (@td_tag) {

            #Check if contains ABC and than procede to fetch the download href link.
            if ($_->look_down(_tag  => 'td', class => qr{[c]}, sub {
                        $_[0]->as_text eq 'ABC';} )
            )   
            {   
                my $text = $_->as_text;
                say "Current node text is: ", $text; #outputs ABC

                #Now from here how do I get the link I want to extract.
            }
        }
    }
}

现在,我的方法是先从td tags提取值,如果成功,则将其与用户指定的值进行匹配,然后查找另一个用户指定的值( ABC or DEF对于我而言,如果匹配则为ABC ,而不是仅提取链接) 。

现在,标签containig ABC or DEF没有固定位置,但它们将位于包含5 and 1值的标签下方。 因此,我使用了$_[0]->as_text eq 'ABC'; 要检查标签现在在我的树中是否包含ABC ,我目前在text node ABC处,如何从中提取链接href,即如何在对象树中上移并提取值。

PS:我会在这里尝试过xpath,但是html元素的位置定义和结构都不那么好。

编辑:

因此,我尝试了$_->tag()并返回了td但是如果我在td标记上,则以下代码为什么不起作用:

my $link_obj = $_->look_down(_tag => 'a') # It should look for `a` tag.
say $link_obj->as_text;

但是它给出了以下错误:

Can't call method "as_text" on an undefined value.
3 个回复

我希望以下内容(使用我自己的Marpa :: R2 :: HTML)会有所帮助。 请注意,HTML :: TreeBuilder答案仅找到一个答案。 下面的代码找到两个,我认为这是故意的。

#!perl

use Marpa::R2::HTML qw(html);

use 5.010;
use strict;
use warnings;

my $answer = html(
    ( \join q{}, <DATA> ),
    {   td => sub { return Marpa::R2::HTML::contents() },
        a  => sub {
            my $href = Marpa::R2::HTML::attributes()->{href};
            return undef if not defined $href;
            return [ link => $href ];
        },
        'td.c' => sub {
            my @values = @{ Marpa::R2::HTML::values() };
            if ( ref $values[0] eq 'ARRAY' ) { return $values[0] }
            return [ test => 'OK' ] if Marpa::R2::HTML::contents eq 'ABC';
            return [ test => 'OK' ] if Marpa::R2::HTML::contents eq 'DEF';
            return [ test => '' ];
        },
        tr => sub {
            my @cells = @{ Marpa::R2::HTML::values() };
            return undef if shift @cells != 5;
            return undef if shift @cells != 1;
            my $ok = 0;
            my $link;
            for my $cell (@cells) {
                my ( $type, $value ) = @{$cell};
                $ok = 1 if $type eq 'test' and $value eq 'OK';
                $link = $value if $type eq 'link';
            }
            return $link if $ok;
            return undef;
        },
        ':TOP' => sub { return Marpa::R2::HTML::values(); }
    }
);

die "No parse" if not defined $answer;
say join "\n", @{$answer};

__DATA__
<table>
    <tbody>

        <tr class="epeven completed">
            <td>5</td>
            <td>1</td>
            <td class="c">ABC</td>
            <td class="c">satus</td>
            <td class="c"><a href="/path/link">Download</a></td>
        </tr>
        <tr class="epeven completed">
            <td>5</td>
            <td>1</td>
            <td class="c">status</td>
            <td class="c">DEF</td>
            <td class="c"><a href="/path2/link">Download</a></td>
        </tr>


    </table>

我不确定我了解您要做什么,但是这些方面的内容呢? 使用look_down描述您想要的内容,无需尝试在树上导航。 那将是脆弱的。

use strict;
use warnings;
use HTML::TreeBuilder 5 -weak;
use 5.014;

my $tree = HTML::TreeBuilder->new_from_content(<DATA>);


for my $e ($tree->look_down( _tag => 'a',
                             sub { my $e = $_[0];
                                   my $tr = $e->parent->parent; ### Could also use ->lineage to search up through the 
                                                                ### containing elements
                                   return unless $tr->attr('_tag') eq 'tr' and $tr->attr('class') eq 'epeven completed';
                                   return (     $tr->look_down( _tag => 'td', sub { $_[0]->as_text eq '1'; })
                                            and $tr->look_down( _tag => 'td', sub { $_[0]->as_text eq '5'; })
                                            and $tr->look_down( _tag => 'td', class => 'c', sub { $_[0]->as_text eq 'ABC'; })
                                          );
                                 }
                           )
          ) {
    say $e->attr('href');
}


__DATA__

<table>
    <tbody>

        <tr class="epeven completed">
            <td>5</td>
            <td>1</td>
            <td class="c">ABC</td>
            <td class="c">satus</td>
            <td class="c"><a href="/path/link">Download</a></td>
        </tr>
        <tr class="epeven completed">
            <td>5</td>
            <td>1</td>
            <td class="c">status</td>
            <td class="c">DEF</td>
            <td class="c"><a href="/path2/link">Download</a></td>
        </tr>


    </table>

输出:

/path/link

如果您可以放弃HTML :: TreeBuilder,则可以解析如下内容:

for my $r ($content =~ m{<tr class="epeven completed">(.*?)</tr>}gs) {
    my ($n1, $n2) = $r =~ m{<td>(\d+)</td>\s*<td>(\d+)</td>}g;
    next if $n1 != 5 || $n2 != 1;
    next if $r !~ m{<td class="c">ABC</td>}g;
    my ($link) = $r =~ m{<a href="(.*?)">Download</a>}g;
    say $link;
}
1 向上或向下移动树中的节点

在树视图中上下移动节点的最准确方法是什么。 我在每个节点上都有一个上下文菜单,所选节点应该随其所有子节点一起移动。 我正在使用C#.Net 3.5 WinForms ...

2 将树节点上移一个级别

因此,基本上,我有一棵有序的二叉树,并且我希望能够在不弄乱树的顺序和内容的情况下,将节点替换为其父节点。 因此,根节点必须放置在另一侧的节点下(节点位于其父节点的左侧,因此父节点必须放置在节点的右侧,以免破坏顺序。)解释一般算法,我将如何去做? ...

3 使用R从HTML节点树中提取文本

我目前正在尝试从已解析如下的HTML树中抓取文本:- 我的第一次尝试只是在生成的向量上使用grep,但这失败了。 我的下一个尝试是在查询中的各个点上使用grep.IMDB向量:- 但这也会引发闭包而不是子集错误。 最后在grep抛出周围尝试上面没有data[]函数 ...

5 在嵌套列表中,如何将树节点(通过名称匹配)向上移动一级?

介绍 假设我有一个列表列表...。现在,我知道该树中的某些元素碰巧只是一个元素的列表。 我也知道这些元素的名称。 问题 问题:如何遍历树并取消嵌套(剥离一层)这些元素? 我正在寻找一个带有两个参数的函数:1.输入列表2.要剥离的元素名称。 例 在下面的示例中 ...

2019-02-19 16:07:42 0 40   r/ list
6 如何覆盖设备树并移动节点?

我有一个dts文件,其中包含一个相当通用的dtsi文件,但需要从一个子树中删除一个节点并将其移动到另一个子树。 如果我只是进入基本dts并将节点添加到应有的位置,则生成的dtb既有原始的,也有新的。 原始dtsi: 覆盖: 问题是我然后在“ b1”和“ b2”中都有一个“ ...

7 如何使用html链接提取文本?

我尝试使用BaseX解析HTML页面。 从这部分代码中: 我需要a HTML链接提取消息, 并在开头删除第一个:字符。 我想获得这个确切的文本: 使用此功能, 我可以提取文本,但是从一开始就没有删除: 。 即: ...

9 如何使用按钮上下移动spriteKit节点

我想使用按钮上下移动精灵。 由于您不能在Sprite Kit中使用UIButtons,因此我使用了不同的SpriteKitNodes。 节点将是箭头图像。 但是我想使用箭头图像来移动我的原始精灵,而只需触摸它即可。 我以为我会用SKAction,但是我被卡住了。 是否可以将一个精灵移动 ...

10 如何在VB .NET中上移XML节点

给定这样的XML结构: 我想将&lt;Units&gt;节点移动到&lt;LandXML&gt;下的顶部,因此它出现在Surfaces节点之上,并且我需要将&lt;SourceData&gt;节点移动到&lt;Surface&gt; 。 这是我想要的最终结构: 到目前为止, ...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2021 STACKOOM.COM