我有一个Perl脚本,它从远程服务器下载大量文件。我希望避免锤击服务器,所以如果自从上次检查后未修改文件,我想避免下载文件。有没有一种很好的方法来做到这一点,无论是在Perl或shell脚本?使用perl(或wget)下载新的/修改的文件
我可以让服务器发送HTTP 304而不是HTTP 200用于未修改的文件吗?
我有一个Perl脚本,它从远程服务器下载大量文件。我希望避免锤击服务器,所以如果自从上次检查后未修改文件,我想避免下载文件。有没有一种很好的方法来做到这一点,无论是在Perl或shell脚本?使用perl(或wget)下载新的/修改的文件
我可以让服务器发送HTTP 304而不是HTTP 200用于未修改的文件吗?
是的,请使用LWP::UserAgent
,并特别注意mirror
方法。这在程序LWP::Simple
中也可用作mirror
函数。
从LWP
的POD:
该方法将得到由$ URL标识的文件并将其存储在文件名为$文件名。如果该文件已经存在,则该请求将包含与该文件的修改时间匹配的“If-Modified-Since”标头。如果服务器上的文档自此以后没有更改,则不会有任何反应。如果文档已更新,则会再次下载。该文件的修改时间将被迫与服务器的修改时间相匹配。
返回值是响应对象。
HTTP 304是服务器将返回的响应代码,如果您通过If-Modified-Since测试并且您的副本是新鲜的。 LWP通过mirror
在内部完成 - 您无需担心。
谢谢。有没有办法让它发送一个If-Modified-Since而没有真正的文件?我下载文件,检查它们是否正确,如果不是,则进行诊断。否则,我只是删除该文件并继续。 – Charles 2010-08-04 20:59:00
是的。有。但是,使用LWP时,需要使用[HTTP :: Request](http://search.cpan.org/~gaas/libwww-perl-5.836/lib/HTTP/Request.pm)和'$ ua- > request()'直接。查看[LWP :: UserAgent]的源代码(http://cpansearch.perl.org/src/GAAS/libwww-perl-5.836/lib/LWP/UserAgent.pm)阅读mirror sub defn。如果你希望透明地发生这种情况,你也可以继承'LWP :: UserAgent'并覆盖镜像,子类化'LWP :: UserAgent'确实允许你做一些非常棒的事情。 – 2010-08-04 21:48:53
我很高兴看到有什么东西存在。如果是这样,我已经准备好编写套接字接口了,但是看起来我不需要做更多的事情,而只需编写一些HTTP和一小段Perl。 感谢您的所有建议!我之前没有听说过LWP ......我想我需要花更多时间在CPAN上。 – Charles 2010-08-05 02:51:36
这是基于埃文卡罗尔的回答,但我要详细说明这种情况对其他人有用。我剔除了响应部分;我怀疑我的部分代码会很有趣。
#!/usr/bin/perl -w
require HTTP::Date;
require LWP::UserAgent;
require Date::Parse;
my $lastChecked = '2009-01-01';
my $ua = LWP::UserAgent->new;
$ua->default_header('If-Modified-Since' => HTTP::Date::time2str(Date::Parse::str2time($lastChecked)));
my $response = $ua->get('http://example.com/');
if ($response->code == 304) {
print "No changes.\n";
} elsif ($response->is_success) {
print $response->decoded_content;
} else {
print "Response was error " . $response->code . ": '" . $response->status_line . "'\n";
}
rsync不是您可以实现的解决方案,而不是使用HTTP协议? – Wrikken 2010-08-04 20:11:04
@Wrikken:不,它不是我的服务器! – Charles 2010-08-04 20:13:04