1

foreachリンクをループするためにa を使用しています。ループを続行するにはが必要です$mech->back();か、それとも暗黙的ですか。

$mech2さらに、ネストされた for each ループ用に個別のオブジェクトが必要ですか?

私が現在持っているコードはスタックし (完了しません)、見つからない最初のページで終了します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 をループしています。ページはすぐにレンダリングされないため、次のアクションを決定する前に、特定のページ要素が表示されているかどうかをテストする必要があります (テストで 2 つの xpath を除いて M​​echanize::Firefox ドキュメントの提案と同様)。

ページは最終的に、約 2 ~ 3 秒後に xpath を「情報なし」または必要なものにレンダリングします。情報がない場合は、次の URL に移動します。両方の xpath が同時に存在しないというある種の競合状態があり、MozRepl::RemoteObject: TypeError: can't access dead objectエラーが断続的に発生していると思います (sleep 1奇妙なことにループ内で)。

動作/信頼性を向上させるように思われる私の解決策は、すべての$mech->getand$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
};

他の人はこれに関する改善を提案するかもしれません。

于 2014-04-06T09:31:59.233 に答える