2010-08-04 83 views
3

我有一個Perl腳本,它從遠程服務器下載大量文件。我希望避免錘擊服務器,所以如果自從上次檢查後未修改文件,我想避免下載文件。有沒有一種很好的方法來做到這一點,無論是在Perl或shell腳本?使用perl(或wget)下載新的/修改的文件

我可以讓服務器發送HTTP 304而不是HTTP 200用於未修改的文件嗎?

+0

rsync不是您可以實現的解決方案,而不是使用HTTP協議? – Wrikken 2010-08-04 20:11:04

+0

@Wrikken:不,它不是我的服務器! – Charles 2010-08-04 20:13:04

回答

5

是的,請使用LWP::UserAgent,並特別注意mirror方法。這在程序LWP::Simple中也可用作mirror函數。

LWP的POD:

該方法將得到由$ URL標識的文件並將其存儲在文件名爲$文件名。如果該文件已經存在,則該請求將包含與該文件的修改時間匹配的「If-Modified-Since」標頭。如果服務器上的文檔自此以後沒有更改,則不會有任何反應。如果文檔已更新,則會再次下載。該文件的修改時間將被迫與服務器的修改時間相匹配。

返回值是響應對象。

HTTP 304是服務器將返回的響應代碼,如果您通過If-Modified-Since測試並且您的副本是新鮮的。 LWP通過mirror在內部完成 - 您無需擔心。

+0

謝謝。有沒有辦法讓它發送一個If-Modified-Since而沒有真正的文件?我下載文件,檢查它們是否正確,如果不是,則進行診斷。否則,我只是刪除該文件並繼續。 – Charles 2010-08-04 20:59:00

+2

是的。有。但是,使用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

+1

我很高興看到有什麼東西存在。如果是這樣,我已經準備好編寫套接字接口了,但是看起來我不需要做更多的事情,而只需編寫一些HTTP和一小段Perl。 感謝您的所有建議!我之前沒有聽說過LWP ......我想我需要花更多時間在CPAN上。 – Charles 2010-08-05 02:51:36

1

這是基於埃文卡羅爾的回答,但我要詳細說明這種情況對其他人有用。我剔除了響應部分;我懷疑我的部分代碼會很有趣。

#!/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"; 
}