创建一个perl脚本(W10上的Strawberry perl v5.32.0(来下载我的谷歌日历。谷歌为"basic.ics"文件提供了一个"私有"(无需登录(url。当在我的浏览器(firefox(中打开这个url时,会弹出一个窗口来下载这个"basic.ics"文件。保存时,文件是UTF-8编码的。
在我的脚本中,我使用WWW::Mechanize get ":content_file"
下载文件:
#!/usr/bin/perl -w
use WWW::Mechanize;
# URL modified for obvious reasons ...
my $url = 'https://calendar.google.com/path-to-private-calendar-file/basic.ics';
my $local_file_name = 'Calendar.ics';
my $mech = WWW::Mechanize->new();
$mech->get( $url, ":content_file" => $local_file_name );
然而,与$mech->get
一起收到的文件是ANSI编码的,包含"grabich"(我想不是"翻译的"UTF-8数据(。
如何使get :content_file
创建UTF-8编码的本地文件?
还是直接下载文件,稍后将其转换为UTF-8?如果是这样的话,请告诉我正确的方向,因为将ANSI编码的文件读取为UTF-8并不能起到作用。。。
这与UTF-8或字符编码无关。您得到的是gzip压缩响应。
如果Compress::Zlib可用,WWW::Mechanical默认提供以下标头:
Accept-Encoding: gzip
这允许远程端压缩响应。如果是,远程端将在响应中提供以下标头:
Content-Encoding: gzip
这是在这里发生的,您正在保存压缩的响应。
您可以使用:content_cb
而不是:content_file
来提供一个回调来解压缩数据并存储它。或者,您可以通过提供以下标头来请求一个未压缩的版本:
Accept-Encoding: identity
这是使用完成的
$mech->get($url,
Accept_Encoding => 'identity',
":content_file" => $local_file_name,
);
如果您不需要WWW::Mechanical的开销,为什么不使用它的基类LWP::UserAgent呢。默认情况下,它不提供Accept-Encoding
,因此服务器不太可能对响应进行gzip
my $ua = LWP::UserAgent->new();
# Will work 99.999% of the time.
$ua->get($url, ":content_file" => $local_file_name);
# Definitely works.
$ua->get($url,
Accept_Encoding => 'identity',
":content_file" => $local_file_name,
);
很抱歉我回复晚了,但我还有一些其他事项要处理。感谢ikegami和Hakon的回复和解决方案。
从你的回复中,我提炼出了4种方法,可以获得可读的UTF-8编码的非压缩结果文件:
- 机械化+内容文件和编码
- UserAgent+Content_file,无编码
- UserAgent+内容文件和编码
- UserAgent+将内容打印到文件
然而,在最后一种情况下,每行末尾都有一个额外的CR
(CRCRLF
而不是CRLF
(,但没有什么是一个小正则表达式无法解决的。。。
这是我的测试结果:
CASE 1: Mechanize + Content_file and encoding ...
Get: $mech1->get($url, Accept_Encoding => 'identity', ":content_file" => $fn1)
Calendar1.ics received, size = 78564 bytes
CASE 2: UserAgent + Content_file, no encoding ...
Get: $ua2->get($url, ":content_file" => $fn2);
Calendar2.ics received, size = 78564 bytes
CASE 3: UserAgent + Content_file and encoding ...
Get: $ua3->get($url, Accept_Encoding => 'identity', ":content_file" => $fn3);
Calendar3.ics received, size = 78564 bytes
CASE 4: UserAgent + print content to file ...
Get: my $res4 = $ua4->get($url);
...
my $content = $res4->content;
$content =~ s/r[n]*/n/gm;
print $fh $content;
...
Calendar4.ics received, size = 78564 bytes
是的,我在使用WWW::Mechanical时也会得到一些加密文件,但LWP::UserAgent对我来说很好:
use feature qw(say);
use strict;
use warnings;
use LWP::UserAgent;
my $fn = 'Calendar.ics';
my $url = 'https://calendar.google.com/calendar/XXXXXXXX/basic.ics';
my $ua = LWP::UserAgent->new();
my $res = $ua->get( $url );
if ($res->is_success) {
say "Saving file: '$fn'";
open ( my $fh, '>', $fn ) or die "Could not open file '$fn': $!";
print $fh $res->content;
close $fh;
}
else {
die $res->status_line;
}