繁体   English   中英

WWW :: Mechanize :: Firefox通过链接循环

[英]WWW::Mechanize::Firefox looping though links

我正在使用一个foreach来遍历链接。 我需要$mech->back();$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();
    }
}

我建议为此使用单独的$ 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();
#    }
}

当页面上不再显示信息时,您将无法访问该信息。 但是, 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');
    }
}

更新

我很抱歉。 似乎follow_link挑剔,需要在当前页面上关注链接。

我建议您从每个链接中提取href属性,并使用get而不是follow_link

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');
    }
}

请让我知道这在您连接的网站上是否有效。

我正在使用WWW:Mechanize :: Firefox遍历一堆带有Javascript负载的URL。 该页面不会立即呈现,因此需要测试某个页面元素是否可见(类似于Mechanize :: Firefox文档中的建议,但测试中有2个xpath),然后再决定下一步。

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

我的可行/提高可靠性的解决方案是将所有$mech->get $mech->is_visible $mech->get$mech->is_visibleeval{}; 像这样:

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
};

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

暂无
暂无

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

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