Perl - 使用WWW :: Mechanize获取

时间:2017-04-17 13:34:33

标签: perl mechanize 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>

我想提取此链接

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

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

1 个答案:

答案 0 :(得分:2)

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

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

<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">

此处4中的content表示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,直到它们完成处理。由于这是一个非常简单的文档,我们可以安全地使用模式匹配。网址始终相同,并且标有<strong>标记。在general it's not a good idea to use regex to parse HTML,但我们并没有真正解析,我们只是screenscraping一个值。 \Q\Equotemeta相同,请确保我们不必转义.?,然后\比模式中有一些反斜杠import java.util.concurrent.TimeUnit; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.chrome.ChromeDriver; import org.openqa.selenium.support.ui.ExpectedConditions; import org.openqa.selenium.support.ui.Wait; import org.openqa.selenium.support.ui.WebDriverWait; public class ch1 { static WebDriver driver; public static void main(String[] args) throws InterruptedException { System.setProperty("webdriver.chrome.driver", "C://testing/chromedriver_win32/chromedriver.exe"); driver = new ChromeDriver(); try{ driver.get("https://www.via.com"); driver.findElement(By.xpath("//*[@id='wzrk-cancel']")).click(); } finally{ driver.manage().timeouts().implicitlyWait(5000, TimeUnit.MILLISECONDS); driver.findElement(By.xpath("//input[@class='ui-autocomplete-input']")).sendKeys("BLR"); driver.findElement(By.xpath("//*[@id='round-trip-panel']/div[3]/div/div")).click(); WebElement date = driver.findElement(By.xpath("//*[@id='depart-cal']/div[3]/div[2]/div[5]/div[text()='19']")); Wait.until(ExpectedConditions.visibilityOf(date)); date.click(); } } } 更容易阅读。

在每次尝试之后,脚本将sleep持续十秒钟,然后再次尝试。一旦匹配,就会突破无限循环,因此您可以处理具有您想要的数据的实际响应。

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

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