2013-03-11 2 views
1

foreach 링크를 통해 루프를 사용하고 있습니다. 루프를 계속하려면 $mech->back();이 필요합니까, 아니면 암시 적입니까?링크를 통해 WWW :: Mechanize :: Firefox 루핑

각 루프에 중첩 된 별도의 $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(); 
    } 
} 

답변

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 특성을 추출하고 follow_link 대신 get을 사용하는 것이 좋습니다.

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

연결하려는 사이트에서 작동하는지 여부를 알려주십시오.

+0

감사합니다. 훨씬 더 우아한 솔루션입니다. Mozrepl :: RemoteObject : TypeError -이 줄에서 죽은 개체에 액세스 할 수 없습니다. = $ mech-> follow_link ($ share); #it는 위의 그림과 같습니다. 중첩 된 문제는 ... 이전 답변에서 제안한대로 별도의 mech 객체가 필요합니까? – surfer190

+0

죄송합니다. $ mech-> follow_link ($ place); – surfer190

+0

[* 최신 수정 목록 *] (http://cpansearch.perl.org/src/CORION/WWW-Mechanize-Firefox-0.70/Changes) Firefox 15에서 시작된 "죽은 객체"문제처럼 보입니다. 대안을 제시하기 위해 내 솔루션을 업데이트했습니다. – Borodin

1

나는이에 대해 별도의 $ 기계화 객체를 사용하는 것이 좋습니다 :이 화면에 더 이상있을 때 당신은 페이지에서 정보에 액세스 할 수 없습니다

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(); 
# } 
} 
+0

왜 Mechanize 객체를 여러 개 추천합니까? – Borodin

+0

예를 들어이 코드를 여러 스레드와 함께 사용하기 쉽게 변경할 수 있기 때문입니다. 나는 고전적인 WWW에 대해 말하고있다 : 물론 파이어 폭스가 아니라 기계화. – gangabass

+0

'clone' 메쏘드는 결코 구현되지 않을 가능성이있는 함수 * 아래의 모듈 문서에 열거되어 있습니다. 아마 당신은 피난처를 테스트하지 않았을 것입니까? – Borodin

0

나는 WWW : Mechanize :: Firefox를 사용하여 수많은 자바 스크립트로 루프를 반복합니다. 페이지가 즉시 렌더링되지 않으므로 다음 동작을 결정하기 전에 특정 페이지 요소가 표시되는지 테스트해야합니다 (테스트에서 2 xpaths를 제외한 Mechanize :: Firefox 문서의 제안과 유사).

페이지는 결국 xpath를 '정보 없음'또는 약 2-3 초 후에 원하는 정보로 렌더링합니다. 정보가 없으면 다음 URL로 이동합니다. 두 개의 xpath가 동시에 존재하지 않는 경쟁 조건이 있다고 생각합니다. MozRepl::RemoteObject: TypeError: can't access dead object 오류가 간헐적으로 발생합니다 (회 돌이가 충분히 이상합니다)./ 작동 신뢰성을 향상시킬 것

내 솔루션은이 같은 eval{};의 모든 $mech->get$mech->is_visible를 동봉하는 것입니다

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

다른 사람들은 이에 대한 개선을 제안 할 수 있습니다.

관련 문제