我有一个网站,里面有一堆绝对地址,我需要将它(该网站的全部内容)上移一级,因此所有绝对链接都需要转换为相对链接。
我知道获得和--转换链接,但在我的例子中不起作用。我的网站实际上是用 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 }