代码之家  ›  专栏  ›  技术社区  ›  tread

WWW::机械化::Firefox通过链接循环

  •  1
  • tread  · 技术社区  · 13 年前

    我正在使用 foreach 通过链接循环。我需要一个吗 $mech->back(); 继续循环,或者这是隐含的。

    此外,我需要一个单独的吗 $mech2 为每个循环嵌套的对象?

    我目前拥有的代码被卡住了(它没有完成),并在第一页结束 td#tabcolor3 未找到。

    foreach my $sector ($mech->selector('a.link2'))
    {
        $mech->follow_link($sector);
    
        foreach my $place ($mech->selector('td#tabcolor3'))
        {
                if (($mech->selector('td#tabcolor3', all=>1)) >= 1)
        {
            $mech->follow_link($place);
                print $_->{innerHTML}, '\n'
                for $mech->selector('td.dataCell');
            $mech->back();
        }
        else
        {
            $mech->back();
        }
    }
    
    3 回复  |  直到 13 年前
        1
  •  1
  •   Borodin    13 年前

    当页面不再显示时,您无法访问该页面中的信息。然而 foreach 工作就是建立列表 第一 在迭代之前,所以您编写的代码应该很好。

    没有必要打电话给 back 因为链接是绝对的。如果你使用过 click 那么页面中必须有一个链接可以点击,但是 follow_link 你所要做的就是转到一个新的URL。

    也没有必要检查要关注的链接数量,因为 for 空列表上的循环将不会被执行。

    为了让事情更清楚,我建议你分配 selector 到循环之前的数组。

    这样地

    my @sectors = $mech->selector('a.link2');
    for my $sector (@sectors) {
    
        $mech->follow_link($sector);
    
        my @places = $mech->selector('td#tabcolor3');
        for my $place (@places) {
    
            $mech->follow_link($place);
    
            print $_->{innerHTML}, '\n' for $mech->selector('td.dataCell');
        }
    }
    

    使现代化

    我很抱歉。看起来 跟随链接(_L) 很挑剔,需要遵循链接 在当前页面上 .

    我建议你提取 href 每个链接的属性并使用 get 而不是 跟随链接(_L) .

    my @selectors = map $_->{href}, $mech->selector('a.link2');
    for my $selector (@selectors) {
    
        $mech->get($selector);
    
        my @places = map $_->{href}, $mech->selector('td#tabcolor3');
        for my $place (@places) {
    
            $mech->get($place);
    
            print $_->{innerHTML}, '\n' for $mech->selector('td.dataCell');
        }
    }
    

    请让我知道这是否适用于您正在连接的网站。

        2
  •  1
  •   gangabass    13 年前

    我建议为此使用单独的$mech对象:

    foreach my $sector ($mech->selector('a.link2'))
    {
        my $mech = $mech->clone();
        $mech->follow_link($sector);
    
        foreach my $place ($mech->selector('td#tabcolor3'))
        {
                if (($mech->selector('td#tabcolor3', all=>1)) >= 1)
        {
                my $mech = $mech->clone();
                $mech->follow_link($place);
                print $_->{innerHTML}, '\n'
                for $mech->selector('td.dataCell');
            #$mech->back();
        }
    #    else
    #    {
    #        $mech->back();
    #    }
    }
    
        3
  •  0
  •   d586    12 年前

    我正在使用WWW:Machimie::Firefox在一堆带有Javascript负载的URL上循环。页面不会立即呈现,因此在决定下一步操作之前,需要测试特定页面元素是否可见(类似于Mechanize::Firefox文档中的建议,除了测试中的2个xpath)。

    大约2-3秒后,页面最终将xpath呈现为“无信息”或一些想要的东西。如果没有信息,我们将转到下一个URL。我认为存在某种竞赛条件,两个xpath不同时存在,导致 MozRepl::RemoteObject: TypeError: can't access dead object 间歇性错误(在 sleep 1 奇怪的是,在循环中)。

    我的解决方案似乎有效/提高了可靠性,那就是将所有 $mech->get $mech->is_visible eval{}; 这样地:

    eval{ 
      $mech->get("$url");
      $retries = 15; #test to see if element visible = page complete
      while ($retries-- and ! $mech->is_visible( xpath => $xpath_btn ) and  ! $mech->is_visible( xpath => $xpath_no_info )){
        sleep 1;
      };
      last if($mech->is_visible( xpath => $xpath_no_info) ); #skip rest if no info page
    };
    

    其他人可能会建议对此进行改进。

    推荐文章