Как извлечь информацию из веб-страницы с помощью Perl? - PullRequest
1 голос
/ 02 сентября 2011

Мне нужно извлечь самые большие значения (количество) конкретных имен с веб-страницы.Рассматривайте веб-страницу как

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

, а содержание URL -

<!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 и 168является наибольшим для PRE-UPG-LATEST-5.3.0

Как мне извлечь эти значения и поместить их в переменную, скажем, $ gtp и $ pre в 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 ]

4 голосов
/ 02 сентября 2011

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 голос
/ 02 сентября 2011

Я бы посоветовал вам использовать не только 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;
    }
}
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...