如何使用perl从网页中提取信息?

时间:2011-09-02 12:26:30

标签: perl parsing webpage

我需要从网页中提取特定名称的最大值(数量)。将网页视为

 http://earth.wifi.com/isos/preFCS5.3/upgrade/

,网址内容为

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<html>
 <head>
  <title>Index of /isos/preFCS5.3/upgrade</title>
 </head>
 <body>
<h1>Index of /isos/preFCS5.3/upgrade</h1>
<table><tr><th><img src="/icons/blank.gif" alt="[ICO]"></th><th><a href="?C=N;O=D">Name</a></th><th><a href="?C=M;O=A">Last modified</a></th><th><a href="?C=S;O=A">Size</a></th><th><a href="?C=D;O=A">Description</a></th></tr><tr><th colspan="5"><hr></th></tr>
<tr><td valign="top"><img src="/icons/back.gif" alt="[DIR]"></td><td><a href="/isos/preFCS5.3/">Parent Directory</a></td><td>&nbsp;</td><td align="right">  - </td></tr>
<tr><td valign="top"><img src="/icons/unknown.gif" alt="[   ]"></td><td><a href="GTP-UPG-LATEST-5.3.0.160.iso">GTP-UPG-LATEST-5.3.0.160.iso</a></td><td align="right">29-Aug-2011 16:06  </td><td align="right">804M</td></tr>
<tr><td valign="top"><img src="/icons/unknown.gif" alt="[   ]"></td><td><a href="GTP-UPG-LATEST-5.3.0.169.iso">GTP-UPG-LATEST-5.3.0.169.iso</a></td><td align="right">31-Aug-2011 16:26  </td><td align="right">804M</td></tr>
<tr><td valign="top"><img src="/icons/unknown.gif" alt="[   ]"></td><td><a href="GTP-UPG-LATEST-5.3.0.172.iso">GTP-UPG-LATEST-5.3.0.172.iso</a></td><td align="right">01-Sep-2011 16:26  </td><td align="right">804M</td></tr>
<tr><td valign="top"><img src="/icons/unknown.gif" alt="[   ]"></td><td><a href="PRE-UPG-LATEST-5.3.0.157.iso">PRE-UPG-LATEST-5.3.0.157.iso</a></td><td align="right">29-Aug-2011 16:05  </td><td align="right">1.5G</td></tr>
<tr><td valign="top"><img src="/icons/unknown.gif" alt="[   ]"></td><td><a href="PRE-UPG-LATEST-5.3.0.165.iso">PRE-UPG-LATEST-5.3.0.165.iso</a></td><td align="right">31-Aug-2011 16:26  </td><td align="right">1.5G</td></tr>
<tr><td valign="top"><img src="/icons/unknown.gif" alt="[   ]"></td><td><a href="PRE-UPG-LATEST-5.3.0.168.iso">PRE-UPG-LATEST-5.3.0.168.iso</a></td><td align="right">01-Sep-2011 16:26  </td><td align="right">1.5G</td></tr>
<tr><th colspan="5"><hr></th></tr>
</table>
<address>Apache/2.2.3 (Red Hat) Server at earth.wifi.com Port 80</address>
</body></html>

在上面的源代码中,您可以看到172是GTP-UPG-LATEST-5.3.0中最大的 和PRE-UPG-LATEST-5.3.0中最大的168是

如何提取这些值并将其置于变量中,如$ gtp和$ pre in perl

非常感谢

#!/usr/bin/perl 

use strict;
use warnings;

use LWP::Simple; 

my $upgrade = 'http://earth.wifi.com/isos/preFCS5.3/upgrade/';
my $website_content = get($upgrade);
if ( $website_content =~ /href=\"PRE-UPG-LATEST-5.3.0(.*?)\.iso\"/ ) 

{

my $preversion = ${1};

print $preversion;
}

这是我尝试过的代码,但它没有获得最大的值。这是代码获得它遇到的第一个PRE-UPG-LATEST版本值。但我需要最大的值

2 个答案:

答案 0 :(得分:4)

if()只执行一次。由于您想要获得许多,您需要循环

while ( m//g ) {

在你的数据中它有“UPG”,但你的正则表达式有“UGP”,所以它不匹配 (你应该复制/粘贴长字符串而不是(尝试)重新键入它们!)。

这将列出您需要的数据,我将留给您了解如何处理它。

while ($website_content =~ /href="((?:PRE|GTP)-UPG-LATEST-.*?)\.(\d+)\.iso"/g) {
    my($file, $version) = ($1, $2);
    print "file=$file version=$version\n";
}

答案 1 :(得分:1)

我建议你不仅要使用LWP :: Simple,还要使用XML::Simple。这将允许您将数据示例为散列哈希值。找到最大的版本会更容易。

您无法使用简单的正则表达式解析HTML或XML,因为XML数据结构太自由了。大型结构可以合法地在单独的线上分解。看一下这个例子:

<a href="http://foo.com/bar/bar/">The Foobar Page</a>

它也可以表示为:

<a
     href="http://foo.com/bar/bar/">
     The Foobar Page
</a>

如果您正在寻找a href,您将永远找不到它。哎呀,你甚至可以找a\s+href但找不到它。

可能有更好的模块用于解析HTML(我发现HTML::Dom),但我从未使用它们,也不知道哪一个是最好的使用它

至于查找最大版本号:

存在一些困难,因为版本编号存在各种奇怪和古怪的规则。例如:

2.2 < 2.10

Perl有一些名为 V-Strings 的东西,但有传言称它们已被弃用。如果这与您无关,则可以使用Perl::Version

否则,这是一个进行版本比较的子程序。请注意,我还通过/^\d+$/正则表达式验证每个部分是否为整数。我的子程序可以返回四个值:

  • 0:两者大小相同
  • 1:第一个数字更大
  • 2:第二个数字更大
  • undef:出了点问题。

以下是该计划:

my $minVersion  = "10.3.1.3";
my $userVersion = "10.3.2";

# Create the version arrays

my $result = compare($minVersion, $userVersion);

if (not defined $results) {
    print "Non-version string detected!\n";
}
elsif ($result == 0) {
print "$minVersion and $userVersion are the same\n";
}
elsif ($result == 1) {
print "$minVersion is bigger than $userVersion\n";
}
elsif ($result == 2) {
print "$userVersion is bigger than $minVersion\n";
}
else {
print "Something is wrong\n";
}


sub compare {

my $version1 = shift;
my $version2 = shift;

my @versionList1 = split /\./, $version1;
my @versionList2 = split /\./, $version2;

my $result;

while (1) {

    # Shift off the first value for comparison
    # Returns undef if there are no more values to parse

    my $versionCompare1 = shift @versionList1;
    my $versionCompare2 = shift @versionList2;

    # If both are empty, Versions Matched

    if (not defined $versionCompare1 and not defined $versionCompare2) {
    return 0;
    }

    # If $versionCompare1 is empty $version2 is bigger
    if (not defined $versionCompare1) {
    return 2;
    }
    # If $versionCompare2 is empty $version1 is bigger
    if (not defined $versionCompare2) {
    return 1;
    }

    # Make sure both are numeric or else there's an error
    if ($versionCompare1 !~ /\^d+$/ or $versionCompare2 !~ /\^\d+$/) {
    return;
    }

    if ($versionCompare1 > $versionCompare2) {
    return 1;
    }
    if ($versionCompare2 > $versionCompare1) {
    return 2;
    }
}
}