2013-02-13 2 views
0

У меня есть вопрос. Я надеюсь, что вы могли бы помочь?Perl WWW :: Механизировать Сохранять URL-адреса в хеше, если он не найден

foreach my $url (keys %{$newURLs}) { 
    # first get the base URL and save its content length 
    $mech->get($url); 
    my $content_length = $mech->response->header('Content-Length'); 

    # now iterate all the 'child' URLs 
    foreach my $child_url (@{ $newURLs->{$url} }) { 
    # get the content 
    $mech->get($child_url); 

    # compare 
    if ($mech->response->header('Content-Length') != $content_length) { 
     print "$child_url: different content length: $content_length vs " 
     . $mech->response->header('Content-Length') . "!\n"; 
     #HERE I want to store the urls that are found to have different content 
     #lengths to the base url 
     #only if the same url has not already been stored 
    } elsif ($mech->response->header('Content-Length') == $content_length) { 
     print "Content lengths are the same\n"; 
     #HERE I want to store the urls that are found to have the same content 
     #length as the base url 
     #only if the same url has not already been stored 
    } 
    } 
} 

Проблема, которую я имею:

Как вы можете видеть в коде выше, я хочу, чтобы хранить адреса в зависимости от того, если длины содержимого являются одинаковыми или разными, , так что я буду в конечном итоге с группой URL-адресов, у которых была другая длина контента, к их базовому url, и в итоге я получаю еще одну группу URL-адресов, которые имеют одинаковую длину содержимого с их базовым url.

Я знаю, как сделать это легко с помощью массива

push (@differentContentLength, $url); 
push (@sameContentLength, $url); 

Но как бы я идти об этом, используя хэш (или другой предпочтительный метод)?

я все еще получаю, чтобы справиться с хэшей так что ваша помощь будет оценена,

Большое спасибо

+0

Вы должны добавить закрывающие скобки к вашим петлям. – simbabque

+0

@simbabque - да, ваше право, извинения –

ответ

1

Вы можете создать hashref для сохраните все URL-адреса для вас вне цикла. Назовем это $content_lengths. Это скаляр, потому что это ссылка на хэш. В вашем цикле $child_url добавьте длину содержимого к этой структуре данных. Сначала мы будем использовать базовый url, давая нам еще один hashref внутри $content_lengths->{$url}. Там мы решаем, хотим ли мы equal или different. Внутри этих двух ключей будет еще один hashref, удерживающий $child_url s. Они, в свою очередь, имеют длину контента в качестве значений. Конечно, мы могли бы просто сказать ++ здесь, если вы не хотите, чтобы длина была сохранена.

my $content_lengths; # this is at the top 
foreach my $url (# ... more stuff 

# compare 
if ($mech->response->header('Content-Length') != $content_length) { 
    print "$child_url: different content length: $content_length vs " 
    . $mech->response->header('Content-Length') . "!\n"; 

    # store the urls that are found to have different content 
    # lengths to the base url only if the same url has not already been stored 
    $content_lengths->{$url}->{'different'}->{$child_url} = $mech->response->header('Content-Length'); 

} elsif ($mech->response->header('Content-Length') == $content_length) { 
    print "Content lengths are the same\n"; 

    # store the urls that are found to have the same content length as the base 
    # url only if the same url has not already been stored 
    $content_lengths->{$url}->{'equal'}->{$child_url} = $mech->response->header('Content-Length'); 
} 
+0

Когда вы говорите, что здесь используется «++ здесь, если вы не хотите, чтобы длина была сохранена», это так, как это должно быть написано '$ content_lengths -> {$ url} -> {' разные '} -> {$ child_url} ++; '? и для уточнения, что именно делает '++'? –

+1

@ perl-user да, вот что я имею в виду. Это оператор с расширением-сокращением. Он добавляет 1 к var слева и назначает его. Таким образом, все они будут иметь значение 1. Если один из URL-адресов будет показан дважды, значение будет равно 2. Это как счетчики и «запомнить имя, но не заботятся о том, сколько» реализовано. Вы можете получить доступ к нему с помощью клавиш. Подумайте об этом как о «GROUP BY» в SQL. – simbabque

+0

О, я вижу, как это предотвращает дублирование сейчас (используется Data :: Dumper), вместо добавления в него другого дублирующего URL-адреса просто регистрируется его присутствие, увеличивая число, присвоенное этому URL-адресу, что не имеет значения, потому что нас не интересует эта часть, спасибо, ваш комментарий объяснил это хорошо :) –

1

Пожалуйста, проверьте это решение:

my %content_length; 

foreach my $url (keys %{$newURLs}) { 
    # first get the base URL and save its content length 
    $mech->get($url); 
    my $content_length = $mech->response->header('Content-Length'); 

    # now iterate all the 'child' URLs 
    foreach my $child_url (@{ $newURLs->{$url} }) { 
    # get the content 
    $mech->get($child_url); 
    my $new_content_length = $mech->response->header('Content-Length'); 
    # store in hash 
    print "New URL! url: $child_url\n" if ! defined $content_length{$child_url}; 
    print "Different content_length! url: $child_url, old_content_length: $content_length, new_content_length: $new_content_length\n" if $new_content_length != $content_length{$child_url}; 
    $content_length{$child_url} = $new_content_length; 
    } 
}