Назад | Перейти на главную страницу

Замена всех абсолютных ссылок HTML на относительные

У меня есть веб-сайт с множеством абсолютных адресов, и мне нужно переместить его (все содержимое этого веб-сайта) на более высокий уровень, поэтому все абсолютные ссылки необходимо преобразовать в относительные.

Я знаю о wget с участием --convert-links, но в моем случае это не работает. Мой веб-сайт фактически зеркалируется с помощью wget, но когда я повторно очищаю его с помощью параметра timestamp для получения обновлений, --convert-links не работает должным образом. Есть ли другой способ сделать это?

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

Веб-сайт размещен на Apache 2.0, но я не иметь доступ к конфигурации сервера.

Вы можете выполнить поиск и заменить каждый документ на своем сайте, чтобы получить то, что вам нужно. Возможно, используя шаблоны регулярных выражений. В Linux / Unix sed среди других инструментов командной строки могут помочь.

Я не уверен, почему вы говорите о wget и инструментах зеркалирования. У вас нет доступа к файлам?

Этот инструмент говорит, что делает именно то, что вы хотите:

http://www.perlmonks.org/?node_id=56338

Измените абсолютные ссылки на относительные в файлах HTML

Эта утилита будет рекурсивно проходить через указанный каталог, анализировать все файлы .htm и .html и заменять любые абсолютные URL-адреса относительными URL-адресами на заданную вами базу.

Вы также можете указать, какие типы ссылок нужно анализировать: img, src, action или любые другие. Пожалуйста, смотрите хэш% linkElements HTML :: Tagset в исходном коде модуля, чтобы получить точную разбивку поддерживаемых типов тегов.

Эта программа была хорошей практикой для опробования Getopt :: Declare, отличного парсера командной строки. Обратите внимание на спецификацию параметра под ДАННЫЕ тег.

Отказ от ответственности: всегда используйте переключатель -b для принудительного резервного копирования, на всякий случай, если у вас нестандартный HTML и синтаксический анализатор HTML :: TreeBuilder искажает его.

Комментарии и предложения по улучшению всегда приветствуются и очень ценятся.

Если ссылка перестает работать, вот код:

#!/usr/bin/perl -w

use strict;
use Getopt::Declare;
use Cwd;
use File::Find;
use HTML::TreeBuilder;
use URI::URL qw(url);
use File::Copy;
use IO::File;

use vars qw($VERSION $BASE_URL $BACKUP $DIRECTORY @WANTED_TYPES);

$VERSION = (qw$Revision: 1.1 $)[1];

#Load the definition and grab the command-line parameters
my $opts = Getopt::Declare->new( do{ local $/; <DATA> } );

#Cycle through this directory, and all those underneath it
find(\&wanted, $DIRECTORY || getcwd);

#Parse each HTML file and make a backup
#of it using File::Copy::copy.
sub wanted {
  return unless $File::Find::name =~ /html?$/;

  #Extract Links from the file
  my $h = HTML::TreeBuilder->new;
  $h->parse_file($File::Find::name);

  my $link_elements = $h->extract_links(@WANTED_TYPES);
  return unless @$link_elements;

  #Grab each img src and re-write them so they are relative URL's
  foreach my $link_element (@$link_elements) {
    my $link    = shift @$link_element; #URL value
    my $element = shift @$link_element; #HTML::Element Object

    my $url = url($link)->canonical;
    next unless $url->can('host_port') and
      $BASE_URL->host_port eq $url->host_port;

    #Sigh.. The following is because extract_links() doesn't
    #tell you which attribute $link belongs to, except to say
    #it is the value of an attribute in $element.. somewhere.

    #Given the $link, find out which attribute it was for
    my ($attr) = grep {
      defined $element->attr($_) and $link eq $element->attr($_)
    } @{ $HTML::Tagset::linkElements{$element->tag} };

    #Re-write the attribute in the HTML::Element Tree
    #Note: $BASE_URL needs to be quoted here.
    $element->attr($attr, $url->path("$BASE_URL"));
  }

  #Make a backup of the file before over-writing it
  copy $File::Find::name => $File::Find::name.'.bak'
    if defined $BACKUP;

  #Save the updated file
  my $fh = IO::File->new($File::Find::name, O_RDWR)
    or die "Could not open $File::Find::name: $!";
  $fh->print($h->as_HTML);
}

__DATA__
#If there is an error here, you need to have one tab
#between the <$var> and the option description.
 -u <base_url>         Base URL (http://www.yoursite.com) [required]
                      { $BASE_URL = url($base_url)->canonical }
 -b                    Backup changed files
                      { $BACKUP = 1  }
 -d <directory>        Starting Directory to recurse from
                      { $DIRECTORY = $directory }
 -l <links>...         Links to process: img, href, etc [required]
                      { @WANTED_TYPES = @links }