Создание нескольких файлов для каждого tld и сортировка каждого файла - PullRequest
0 голосов
/ 24 декабря 2011

У меня есть список миллионов веб-адресов.Я должен извлечь TLD для каждого URL и сделать несколько файлов для каждого TLD.Например, собрать все веб-адреса с .com как tld и вывести их в 1 файл, другой подать заявку на .edu tld и так далее.Далее в каждом файле я должен отсортировать его в алфавитном порядке по доменным именам, после чего по поддоменам и т. Д. Кто-нибудь может произвести переход для применения этого в perl?

Я использовал модуль URI для извлечения tld и domainимена хостов для каждого веб-адреса.Как собрать все веб-адреса с помощью com tld и сбросить их в 1 файл?И как сортировать каждый файл по tld, затем по домену, затем по поддомену и т. Д.?Есть указатели?

while(my $line = <$fh1>){   

my $url = $line;

 my @components =  split(/\./, $url);
 my $n_comp = ($components[-1] =~ /^edu|com|net|org|gov$/) ? 2 : 3;
 my $domain = lc(join '.', @components[-$n_comp .. -1]);
 $domain =~ s/^\.//;  # Remove leading . if there is one.
 print $fh3 $domain;
        print $fh3 "\n";


  my $host = URI->new($url)->host();

 # Treat relative URLs as absolute URLs with missing http://.
 $url = "http://$url" if $url !~ /^\w+:/;



 $host =~ s/\.\z//;  # D::PS doesn't handle "domain.com.".
 print $fh2 $host;
 print $fh2 "\n";
 $dps->get_root_domain($host)
 or die $dps->error();
 print $fh4 $dps->tld();
 print $fh4 "\n";


 }

1 Ответ

0 голосов
/ 24 декабря 2011

Это должно работать для вас.

use strict;
use warnings;
use autodie;

open my $input, '<', shift @ARGV;
my %domain;
while( <$input> ){
  chomp;
  #                                   (  protocol   ) (  domain ) (rest)
  my ($protocol,$domain,$remain) = /^ (?:(\w+):\/\/)? ([^\\\/#]+) ( .* ) /x;

  my ($tld,@domain) = reverse split /[.]/, $domain;

  my $cmp = join '.', @domain;
  push @{ $domain{$tld} }, [ $cmp, $remain, $_ ];
}
close $input;

while( my($tld,$list) = each %domain ){
  open my $out, '>', $tld;
  print {$out} "$_\n" for map{
    $_->[-1]
  }sort{
    $a->[0] cmp $b->[0] ||
    $a->[1] cmp $b->[1] ||
    $a->[2] cmp $b->[2]
  } @$list;
  close $out;
}

  1. Сначала мы разбиваем входные данные на нужные нам части.

    /^ (?:(\w+):\/\/)? ([^\\\/#]+) ( .* ) /x;
    
    • Это будет соответствовать необязательному http:// или подобному.

      (?:(\w+):\/\/)?
    • Это соответствует чему угодно, кроме \, / и #, так как этосимволы, которые обычно идут после домена.

      ([^\\\/#]+)
    • Это, конечно, соответствует тому, что осталось.

      ( . )
  2. Мы хотим отсортировать URL-адреса от домена верхнего уровня до домена самого низкого уровня.Таким образом, мы разделяем домен, а переворачиваем it.

    my ($tld,@domain) = reverse split /[.]/, $domain;
    
  3. Для сравнения двух URL нам нужна строка, которую просто сравнивать.

    my $cmp = join '.', @domain;
    
  4. Сохраните информацию для дальнейшего использования.

    push @{ $domain{$tld} }, [ $cmp, $remain, $_ ];
    
  5. Откройте файл, который мы собираемся

    while( my($tld,$list) = each %domain ){
      open my $out, '>', $tld;
    
  6. Сортировать список URL-адресов, входящих в текущий файл.

    ...
    sort{
      $a->[0] cmp $b->[0] ||
      $a->[1] cmp $b->[1] ||
      $a->[2] cmp $b->[2]
    } @$list;
    
  7. Отображение списка на фактический URL.

    ...
    map{
      $_->[-1]
    }
    ...
    
  8. Печать для файла каждого URL в списке.

    print {$out} "$_\n" for ...
    
...