如何解决Perl:使用机械化content_file获取UTF-8文件
创建一个perl脚本(W10上的Strawberry Perl v5.32.0)下载我的Google日历。 Google为“ basic.ics”文件提供了“私人”(无需登录)网址。 在浏览器(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编码的,并且包含“ gibberich”(我想不是“翻译的” UTF-8数据)。
如何使get :content_file
创建UTF-8编码的本地文件?
还是我仅按原样下载文件,以后再将其转换为UTF-8? 如果是这样,请指出正确的方向,因为以UTF-8格式读取ANSI编码的文件并不能解决问题。
解决方法
这与UTF-8或字符编码无关。您将收到gzip压缩的响应。
如果Compress :: Zlib可用,则WWW :: Mechanize默认情况下提供以下标头:
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 :: Mechanize的开销,为什么不使用其基类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,);
,
抱歉,我的回复很晚,但我还有其他一些要处理的内容。 感谢ikegami和Hakon的答复和解决方案。
从您的答复中,我已经提炼了4种方法,这些方法获得了可读的UTF-8编码的非压缩结果文件:
- 机械化+ Content_file和编码
- UserAgent + Content_file,无编码
- UserAgent + Content_file和编码
- UserAgent +将内容打印到文件
但是,在最后一种情况下,每行的末尾有一个额外的CR
(CRCRLF
而不是CRLF
),但是一点点的正则表达式都无法解决。 ..
这是我测试的结果:
CASE 1: Mechanize + Content_file and encoding ...
Get: $mech1->get($url,":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,":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::Mechanize时也会得到某种加密的文件,但是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;
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。