【问题标题】:Perl - geturls with WWW::MechanizePerl - 带有 WWW::Mechanize 的 geturl
【发布时间】:2017-04-17 13:34:32
【问题描述】:

我正在尝试在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>

我要提取这个链接

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

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

【问题讨论】:

  • “作业完成后下载结果”您是否希望轮询该地址,直到它提供完成的结果?
  • 实际上我的最终目标是提取出现在该地址上的结果。但我不确定需要多长时间。因此,我想提取地址(bioinfo.noble.org/TrSSP/?sessionid=1492435151653763),然后稍后再提取结果。但我再次不确定这是否是完成这项工作的最佳方式。谢谢。

标签: perl mechanize www-mechanize


【解决方案1】:

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

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

<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 秒。所以这会更早完成。

当然,我们也不知道他们会持续多久。每十秒重新加载一次该页面可能是一种安全的方法(如果您愿意,可以更频繁地)。

您可以通过构建一个简单的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 = $1; # 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 始终相同,并且清楚地标有&lt;strong&gt; 标记。在general it's not a good idea to use regex to parse HTML,但我们并没有真正解析,我们只是screenscraping 一个单一的值。 \Q\Equotemeta 相同,并确保我们不必转义 .?,这比使用一堆反斜杠 \ 更容易阅读在模式中。

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

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

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

【讨论】:

  • 非常感谢。我正在通过多个脚本分多个步骤完成整个过程。提交后,我正在提取正确的网址。之后我正在下载网页,最后是 html 表格解析。你让我的生活更轻松:)。现在我想我可以像这样直接解析我的结果 my $text = read_file($mech); my $te = new HTML::TableExtract(); $te-&gt;parse($text); foreach my $ts ($te -&gt;table_states) { foreach my $row ($ts-&gt;rows) { print " ", join(',', @$row), "\n"; } }
  • @pali 很高兴听到它有效。当您使用它时,请停止使用间接对象表示法。不要做new HTML::TableExtract。请改用HTML::TableExtract-&gt;new。间接对象​​表示法可能会导致语法模棱两可,其中 perl 会混淆等等。 :)
  • 感谢您的见解。
猜你喜欢
  • 2013-07-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-14
  • 2011-10-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多