PERL如何在while循环中跳过错误

时间:2017-12-05 11:58:08

标签: perl

我有这个脚本可以在Instagram上自动执行类似的过程。 除了一件事,它确实应该做它应该做的事情。在while循环中,如果用户不存在,则脚本将死亡。 在这种情况下,应忽略错误,脚本应继续处理列表中的其他用户。

这是我得到的错误:

Error GETing https://www.instagram.com/usernamethatdoesntexist/?__ a=1: Not Found at instagram-post-liker.pl line 29

感谢您的帮助

use WWW::Mechanize;
use JSON;


my $filename = 'data.txt';
open(my $fh, '<:encoding(UTF-8)', $filename)
  or die "Could not open file '$filename' $!";

my $mech_get = WWW::Mechanize->new(agent => 'Mozilla/5.0 (Windows NT 6.0; rv:2.0) Gecko/20100101 Firefox/4.0 Opera 12.14');


my $mecho = WWW::Mechanize->new(agent => 'Mozilla/5.0 (Linux; U; Android 2.2; de-de; HTC Desire HD 1.18.161.2 Build/FRF91) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1');

$mecho->get('https://www.instagram.com/');

$mecho->add_header('Accept-Encoding' => 'gzip, deflate', 'X-Instagram-AJAX' => '1', 'Accept-Language' => 'de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4,pl;q=0.2,nl;q=0.2' ,'X-Requested-With' => 'XMLHttpRequest', 'X-CSRFToken' => getcsrf($mecho));

my $post_data = {
    username    =>  'username',
    password    =>  'password'
};

$mecho->post('https://www.instagram.com/accounts/login/ajax/', $post_data);

  while (my $row = <$fh>) {
  chomp $row;
  print "getting user $row\n";

    $mech_get->get('https://www.instagram.com/'.$row.'/?__a=1');


    my $decoded_json = decode_json( $mech_get->response()->decoded_content() );

     print "Found Post \n";

    $mech_get->get('https://api.instagram.com/oembed/?url=https://www.instagram.com/p/'.$decoded_json->{user}->{media}->{nodes}[0]->{code}.'/');

    my $decoded_json2 = decode_json( $mech_get->response()->decoded_content() );

    print "Linking Post by Id";
    my $post;

    if($decoded_json2->{media_id} =~ /^([^_]*);*)   {
        $post = $1;
    }

    $mecho->add_header('Accept-Encoding' => 'gzip, deflate', 'X-Instagram-AJAX' => '1', 'Accept-Language' => 'de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4,pl;q=0.2,nl;q=0.2' ,'X-Requested-With' => 'XMLHttpRequest', 'X-CSRFToken' => getcsrf($mecho));

    $mecho->post('https://www.instagram.com/web/likes/'.$post.'/like/');

}



sub getcsrf {

    my ($somemech) = @_;

    my $cookies2  = $somemech->response->header('Set-Cookie');


    my $csrf_token2;
    if ($cookies2 =~ /csrftoken=([^;]+);/i){
        return $1;
    }
    else {
        die "Unable to find csrftoken in cookie headers, did something change?";

        }

};

3 个答案:

答案 0 :(得分:2)

您必须使用eval阻止

这里有一些文档: https://perldoc.perl.org/functions/eval.html

另外,您在/

忘记了if($decoded_json2->{media_id} =~ /^([^_]*);*)

您的代码将是

#your code until line 29

eval {$mech_get->get('https://www.instagram.com/'.$row.'/?__a=1');};

if(not $@)
{
    my $decoded_json = decode_json( $mech_get->response()->decoded_content() );

     print "Found Post \n";

    $mech_get->get('https://api.instagram.com/oembed/?url=https://www.instagram.com/p/'.$decoded_json->{user}->{media}->{nodes}[0]->{code}.'/');

    my $decoded_json2 = decode_json( $mech_get->response()->decoded_content() );

    print "Linking Post by Id";
    my $post;

    if($decoded_json2->{media_id} =~ /^([^_]*);*)/   {
        $post = $1;
    }

    $mecho->add_header('Accept-Encoding' => 'gzip, deflate', 'X-Instagram-AJAX' => '1', 'Accept-Language' => 'de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4,pl;q=0.2,nl;q=0.2' ,'X-Requested-With' => 'XMLHttpRequest', 'X-CSRFToken' => getcsrf($mecho));

    $mecho->post('https://www.instagram.com/web/likes/'.$post.'/like/');
}

答案 1 :(得分:1)

通常,任何可能失败的代码都可以放在eval块中,如下所示:

eval {
  # Piece of code that may fail
};
if($@) {
  # In case you want to deal with the error; $@ contains the text describing the error
}

eval中的代码片段将被编译,因此您知道它不包含语法错误。运行时错误将被忽略,但您可以在if块中捕获它。

答案 2 :(得分:0)

禁用WWW :: Mechanize的自动错误处理

默认情况下,WWW :: Mechanize会执行自动错误检查,该错误检查会因错误而死(http://search.cpan.org/~oalders/WWW-Mechanize-1.86/lib/WWW/Mechanize.pm#new())。您可以将autocheck => 0添加到构造函数以禁用此行为。然后,您必须在每次请求后手动检查,方法是检查请求方法的返回值

my $response = $mech->get($url);
unless ($response->is_success) {
    ### add your error handling here
}

或使用WWW :: Mechanize的快捷方式:

$mech->get($url);
unless ($mech->success) {
    ### add your error handling here
}