将所有 HTML 绝对链接更改为相对

将所有 HTML 绝对链接更改为相对

我有一个网站,里面有一堆绝对地址,我需要将它(该网站的全部内容)上移一级,因此所有绝对链接都需要转换为相对链接。

我知道获得--转换链接,但在我的例子中不起作用。我的网站实际上是用 wget 镜像的,但当我使用时间戳选项重新抓取它以获取更新时 --convert-links 无法正常工作。还有其他方法可以解决吗?

此外,该网站规模庞大,因此使用其他镜像工具重新下载是极为不合适的。

该网站由 Apache 2.0 托管,但我不要可以访问服务器配置。

答案1

您可以对站点中的每个文档进行搜索和替换,以获取所需内容。也许可以使用正则表达式模式。在 Linux/Unix 上,sed其他命令行工具可能会有所帮助。

我不确定你为什么要谈论 wget 和镜像工具。你没有访问文件的权限吗?

这个工具说它确实可以满足您的要求:

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

将 HTML 文件中的绝对链接更改为相对链接

此实用程序将递归通过指定的目录,解析所有 .htm 和 .html 文件,并将任何绝对 URL 替换为您定义的基础的相对 URL。

您还可以指定要解析的链接类型:img、src、action 或任何其他类型。请参阅模块源代码中的 HTML::Tagset 的 %linkElements 哈希,以了解受支持的标签类型的精确细分。

这个程序是尝试 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 }

相关内容