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

Ran*_*Rag 7 perl html-parsing

我知道我的问题标题不具有描述性,但让我在这里解释一下.

我试图使用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.
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,我的方法首先从中提取值td tags并将其与用户指定的值匹配,如果它成功,则查找另一个用户指定的值,ABC or DEF在我的情况下,ABC如果它匹配,则仅提取链接.

现在,标签containsig ABC or DEF没有固定的位置,但它们将位于包含5 and 1值的标签下方.所以,我过去$_[0]->as_text eq 'ABC';常常ABC在我的树中包含标签我现在在text nodeABC这里如何提取链接href i,我如何向上移动对象树并提取值.

PS:我会在这里尝试过xpath但是html元素的位置并不是那么明确和结构化的.

编辑:

所以,我尝试$_->tag()并返回,td但如果我在td标签上,而不是以下代码不起作用的原因:

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

但它给出了以下错误:

Can't call method "as_text" on an undefined value.
Run Code Online (Sandbox Code Playgroud)

Oes*_*sor 1

我不确定我是否明白你想要做什么,但是沿着这些思路?使用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>
Run Code Online (Sandbox Code Playgroud)

输出:

/path/link
Run Code Online (Sandbox Code Playgroud)