Perl - geturls WWW::Mechanize

Perl - geturls with WWW::Mechanize

我正尝试在 http://bioinfo.noble.org/TrSSP/ 上提交表单并想提取结果。

我的查询数据是这样的

>ATCG00270
MTIALGKFTKDEKDLFDIMDDWLRRDRFVFVGWSGLLLFPCAYFALGGWFTGTTFVTSWYTHGLASSYLEGCNFLTAA    VSTPANSLAHSLLLLWGPEAQGDFTRWCQLGGLWAFVALHGAFALIGFMLRQFELARSVQLRPYNAIAFSGPIAVFVSVFLIYPLGQSGWFFAPSFGVAAIFRFILFFQGFHNWTLNPFHMMGVAGVLGAALLCAIHGATVENTLFEDGDGANTFRAFNPTQAEETYSMVTANRFWSQIFGVAFSNKRWLHFFMLFVPVTGLWMSALGVVGLALNLRAYDFVSQEIRAAEDPEFETFYTKNILLNEGIRAWMAAQDQPHENLIFPEEVLPRGNAL

我的脚本是这样的

use strict;
use warnings;

use File::Slurp;
use WWW::Mechanize;

my $mech = WWW::Mechanize->new;

my $sequence = $ARGV[0];

$mech->get( 'http://bioinfo.noble.org/TrSSP' );
$mech->submit_form( fields => { 'query_file' => $sequence, }, );

print $mech->content;

#sleep (10);

open( OUT, ">out.txt" );

my @a = $mech->find_all_links();

print OUT "\n", $a[$_]->url for ( 0 .. $#a );

print $mech->content 给出这样的结果

 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
    "http://www.w3.org/TR/html4/loose.dtd">
   <html>

    <head>
      <title>The job is running, please wait...</title>
      <meta http-equiv="refresh" content="4;url=/TrSSP/?sessionid=1492435151653763">
  <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
  <link rel="stylesheet" href="interface/style.css" type="text/css">
</head>

<body>
<table width="90%" align="center" border="0" cellpadding="0" cellspacing="0"  class="table1">

  <tr align="center">
    <td width="50">&nbsp;</td>
    <td></td>
    <td>&nbsp;</td>
  </tr>

  <tr align="left" height="30" valign="middle">
    <td width="30">&nbsp;</td>
    <td bgColor="#CCCCFF">&nbsp;Your sequences have been submitted to backend pipeline, please wait for result:</td>
    <td width="30">&nbsp;</td>
  </tr>

  <tr align="left">
    <td>&nbsp;</td>
    <td>

<br><br><font color="#0000FF"><strong>
&nbsp;</strong></font>
<BR><BR><BR><BR><BR><BR><br><br><BR><br><br><hr>
If you don't want to wait online, please copy and keep the following link to retrieve your result later:<br>

<strong>http://bioinfo.noble.org/TrSSP/?sessionid=1492435151653763</strong>

<script language="JavaScript" type="text/JavaScript">
function doit()
{
    window.location.href="/TrSSP/?sessionid=1492435151653763";
}
setTimeout("doit()",9000);
</script>

    </td>
    <td>&nbsp;</td>
  </tr>
</table>
</body>
    </html>

我想提取这个link

http://bioinfo.noble.org/TrSSP/?sessionid=1492435151653763

并在作业完成后下载结果。但是 find_all_links()/TrSSP/?sessionid=1492434554474809 识别为 link。

我们不知道后端进程需要多长时间。如果是几分钟,你可以让你的程序等待。即使是几个小时,等待也是合理的。

在浏览器中,页面将自行刷新。您显示的响应中实施了两种自动刷新机制。

<script language="JavaScript" type="text/JavaScript">
function doit()
{
    window.location.href="/TrSSP/?sessionid=1492435151653763";
}
setTimeout("doit()",9000);
</script>

javascript setTimeout 接受一个以毫秒为单位的参数,所以这将在 9 秒后完成。

还有一个元标记告诉浏览器自动刷新:

<meta http-equiv="refresh" content="4;url=/TrSSP/?sessionid=1492435151653763">

这里content中的4表示4秒。所以这会早点完成。

当然我们也不知道他们会持续多久。每 10 秒(或更频繁,如果需要)重新加载该页面可能是一种安全的方法。

您可以通过构建一个简单的 while 循环并检查刷新是否仍在响应中来实现。

# do the initial submit here

... 

# assign this by grabbing it from the page
$mech->content =~ m{<strong>(\Qhttp://bioinfo.noble.org/TrSSP/?sessionid=\E\d+)</strong>};
my $url = ; # in this case, regex on HTML is fine

print "Waiting for $url\n";
while (1) {
     $mech->get($url);
     last unless $mech->content =~ m/refresh/;
     sleep 10; # or whatever number of seconds
}

# process the final response ...

我们先提交数据。然后我们提取您应该调用的 URL 直到它们完成处理。由于这是一个非常简单的文档,我们可以安全地使用模式匹配。 URL 总是一样的,并且用 <strong> 标签清楚地标明了。在 general it's not a good idea to use regex to parse HTML, but we're not really parsing, we are just screenscraping a single value. The \Q and \E are the same as quotemeta 中并确保我们不必转义 .?,这比在模式中有一堆反斜杠 \ 更容易阅读.

脚本将在每次尝试后 sleep 持续 10 秒,然后再重试。一旦匹配,它就会跳出无限循环,因此您可以将包含您想要的数据的实际响应的处理放在该循环之后。

在循环中添加一些输出可能有意义,这样您就可以看到它仍然是 运行。

请注意,这需要真正保持 运行 直到完成。不要停止进程。