这是我的第一个问题,所以如果我格式化/问错了,我会提前道歉。
我使用Perl从文件中提取字符串,提交Web表单,并下载由网页创建的新文件。目的是让它在循环中运行30,000个文件,我估计需要大约8天。我正在使用WWW :: Selenium和WWW :: Mechanize来执行Web自动化。我遇到的问题是,如果由于某种原因页面没有正确加载或互联网丢失了一段时间,那么脚本会退出并给出一个错误消息(取决于它失败的阶段):
Error requesting http://localhost:4444/selenium-server/driver/:
ERROR: Could not find element attribute: link=Download PDB File@href
我希望脚本继续运行,进入下一轮循环,所以我不必担心如果一轮循环抛出错误。我的研究表明,使用Try::Tiny
可能是最好的解决方案。目前我只使用try{...}
使用下面的脚本,这似乎可以抑制任何错误并允许脚本继续浏览文件。但是,我担心这似乎是一个非常直率的解决方案,并且无法让我了解文件失败的原因/原因。
理想情况下,我希望将每个出现的文件名和错误消息打印到另一个文件,然后在脚本完成后再进行审核,但我很难理解如何使用catch{...}
来执行此操作或者甚至是正确的解决方案。
use strict;
use warnings;
use WWW::Selenium;
use WWW::Mechanize;
use Try::Tiny;
my @fastas = <*.fasta>;
foreach my $file (@fastas) {
try{
open(my $fh, "<", $file);
my $sequence;
my $id = substr($file, 0, -6);
while (my $line = <$fh>) {
## discard fasta header line
} elsif($line =~ /^>/) { # / (turn off wrong coloring)
next;
## keep line, add to sequence string
} else {
$sequence .= $line;
}
}
close ($fh);
my $sel = WWW::Selenium->new( host => "localhost",
port => 4444,
browser => "*firefox",
browser_url => "http://www.myurl.com",
);
$sel->start;
$sel->open("http://www.myurl.com");
$sel->type("chain1", $sequence);
$sel->type("chain2", "EVQLVESGPGLVQPGKSLRLSCVASGFTFSGYGMHWVRQAPGKGLEWIALIIYDESNKYYADSVKGRFTISRDNSKNTLYLQMSSLRAEDTAVFYCAKVKFYDPTAPNDYWGQGTLVTVSS");
$sel->click("css=input.btn.btn-success");
$sel->wait_for_page_to_load("30000");
## Wait through the holding page - will timeout after 5 mins
$sel->wait_for_element_present("link=Download PDB File", "300000");
## Get the filename part of link
$sel->wait_for_page_to_load("30000");
my $pdbName = $sel->get_attribute("link=Download PDB File\@href");
## Concatenate it with the main domain
my $link = "http://www.myurl.com/" . $pdbName;
$sel->stop;
my $mech = WWW::Mechanize->new( autocheck => 1 );
$mech -> get($link);
#print $mech -> content();
$mech -> save_content($id . ".pdb");
};
}
答案 0 :(得分:4)
您想要查看,记录和查看所有错误(和警告)是完全正确的。 Try::Tiny
提供的机制和语法是简单易用的。
use feature qw(say);
my $errlog = 'error_log.txt';
open my $fh_err, '>', $errlog or die "Can't open $errlog for writing: $!";
foreach my $file (@fastas) {
try {
# processing, potentially throwing a die
}
catch {
say $fh_err "Error with $file: $_"; # NOTE, it is $_ (not $! or $@)
};
}
close $fh_err;
# Remove the log if empty
if (-z $errlog) {
say "No errors logged, removing $errlog";
unlink $errlog or warn "Can't unlink $errlog: $!";
}
您可以在push @failed_files, $file
块内部catch { }
保存处理失败的文件的名称。然后代码可以在主处理之后再次尝试,如果您知道错误主要是由于随机连接问题。拥有失败文件列表非常方便。
请注意,对于v5.14,此模块会解决were fixed的问题,以便正常使用eval
。在这一点上,这主要是一个偏好问题,但请注意Try::Tiny
有一些自己的曲折。有关讨论,请参阅this post。
这解决了简单异常处理的问题,而不是代码的其余部分。