1

我正在使用 aforeach来循环链接。我需要 a$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();
    }
}
4

3 回答 3

1

我建议为此使用单独的 $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();
#    }
}
于 2013-03-11T10:35:13.647 回答
1

当页面不再显示时,您无法从页面访问信息。但是,可行的方法是在迭代之前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');
    }
}

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

于 2013-03-11T10:50:10.260 回答
0

我正在使用 WWW:Mechanize::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_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
};

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

于 2014-04-06T09:31:59.233 回答