【问题标题】:How to download .zip file from web URL using Perl Script?如何使用 Perl 脚本从 Web URL 下载 .zip 文件?
【发布时间】:2012-03-24 01:26:19
【问题描述】:

我想通过点击“以 csv 格式下载文件”下载一个 .zip 文件,该文件位于 URL http://www.nseindia.com/content/equities/cmbhav.htm

如果右键单击“以 csv 格式下载文件”并选择复制链接位置,则 URL 模式将类似于 http://www.nseindia.com/content/historical/EQUITIES/2012/MAR/cm23MAR2012bhav.csv.zip.

我想编写一个从 URL 下载 .zip 文件的 Perl 脚本。

下面的代码不工作

#!/usr/bin/perl
use warnings;
use strict;
use LWP::Simple;

my $url = 'http://www.nseindia.com/content/historical/EQUITIES/2012/MAR' ;
my $file = 'cm23MAR2012bhav.csv.zip'    ;
getstore($url, $file) ;

【问题讨论】:

    标签: perl url download


    【解决方案1】:

    如果您需要更改用户代理,但仍想使用LWP::Simple,可以使用$ua 导出:

    use File::Basename;
    use LWP::Simple qw($ua getstore);
    use URI;
    
    my $url = URI->new( 'http://www.nseindia.com/content/historical/EQUITIES/2012/MAR/cm23MAR2012bhav.csv.zip' );
    
    $ua->default_headers( HTTP::Headers->new(
        Accept => '*/*', 
        )
        );
    
    $ua->agent("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_3) AppleWebKit/534.54.16 (KHTML, like Gecko) Version/5.1.4 Safari/534.54.16");
    
    my $rc = getstore( $url, basename( $url->path ) );
    say "Result is $rc";
    

    事实证明,用户代理字符串和 Accept 标头的组合可以做到这一点。通常,这些问题归结为使您的 LWP 请求看起来就像您的浏览器将发送的请求一样。我使用HTTPScoop 来观察浏览器交易,但是有很多程序可以为你做同样的事情。

    不过,如果事情变得如此复杂,我赞成Mojo::UserAgent。使用交易更容易一些:

    use File::Basename;
    use Mojo::UserAgent;
    use URI;
    
    my $url = URI->new( 'http://www.nseindia.com/content/historical/EQUITIES/2012/MAR/cm23MAR2012bhav.csv.zip' );
    my $file = basename( $url->path );
    printf "URL: %s\nFile: %s\n", $url, $file;
    
    my $response = Mojo::UserAgent->new->name(
        '"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_3) AppleWebKit/534.54.16 (KHTML, like Gecko) Version/5.1.4 Safari/534.54.16"'
        )->get( $url->as_string, { Accept => '*/*' } )->res;
    
    open my $fh, '>', $file or die "Could not open [$file]: $!";
    print $fh $response->body;
    printf "Status: %d\n", $response->code;
    

    【讨论】:

    • 自从我及时尝试后,它对我来说非常有效。如果你不能,你怎么知道它有效?我想知道...我已经从user-agents.org 中获取了用户代理字符串...如果我在 Q/A 网站上像许多用户一样愚蠢的话,我会 -1 的答案(通常这个也不例外)。 此外 不会得到 zip,而是包含指向 zip 的链接的页面。 OP 的错误,我在我的“-1”答案中默默地修复了它。尽管 OP 必须做一些工作来重定向输出或更改一点代码以根据需要保存文件
    • 我怎么知道我可以更改用户代理?我经常这样做。我也直接查看了 HTTP 请求和响应。我不知道你在评论的其余部分想说什么。
    • 不,你怎么知道它会解决问题! (发生在我身上,仅仅改变 User-Agent 是不够的)。这是关于判断的“逻辑过程”的一点,我经常不明白。
    • 我想你错过了我第一个版本中我说我无法判断它是否解决了问题的部分。当我今天早上尝试时,我可以获取资源,所以我修改了我的答案。但是,我对用户代理的特殊更改并不重要。重要的是你可以影响用户代理。
    • 是的,我错过了那部分,抱歉!
    【解决方案2】:

    如果你使用

           print getstore($url, $file);
    

    你看到你得到 403 作为错误(禁止)。

    添加

    用 curl 做实验,他们似乎对用户代理进行了检查,所以你不能使用 LWP::Simple,因为你必须像真正的浏览器一样设置用户代理。

    添加2

    以下作品

    #! /usr/bin/perl -w
    
    use warnings;
    use strict;
    
    use LWP::UserAgent;
    my $url = 'http://www.nseindia.com/content/historical/EQUITIES/2012/MAR/cm23MAR2012bhav.csv.zip';
    #my $file = 'cm23MAR2012bhav.csv.zip';
    #my $url = 'http://localhost:11000';
    
    my $ua = LWP::UserAgent->new;
    $ua->agent("Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3 (FM Scene 4.6.1)");
    my $req = HTTP::Request->new(GET => $url);
    $req->header(Accept => "*/*");
    # $req->remove_header('Connection');  # does not work
    # $req->remove_header('TE');          # does not work
    my $res = $ua->request($req);
    if ($res->is_success)
    {
        print $res->content;
    }
    else
    {
        print $res->status_line, "\n";
    }
    

    标题 TE 和 Connection 不会被 remove_header 行删除,因为它们是在协议级别插入的,因此删除它们是一个不同的过程(我不知道)。

    无论如何,这足以让它发挥作用。

    edit我在UserAgent字符串中有一个最后的空格,导致LWP添加libwww-perl,这就是服务器给出403的原因)

    重要提示

    您必须重定向输出,或更改一些代码以将内容保存到文件中。另请注意,要下载 zip,您必须为其提供正确的 URL,而不是包含 zip 链接的页面的 URL。

    【讨论】:

    • 您可以更改 LWP::Simple 使用的用户代理。
    • 我一直以最简单的方式使用 ::Simple,从未检查过是否可以定制以及可以定制什么!很高兴知道,谢谢。
    • 我再次想知道为什么有人在正确答案上加上-1,这也给出了正确的解决方案。还有一种最简单的方法仍在使用 ::Simple?无论如何,答案仍然是正确的并且有效。有时我会忘记它可能是花费如此糟糕的时间 - 即使几分钟。代码中的额外行只是(个人)尝试让 LWP 发送与 cURL 相同的请求。
    • 您为什么会因为有人反对您喜欢的答案而认为时间浪费了?提问者仍然得到你的答案,你想出了一些东西,它仍然可供世界使用。这些都没有被否决票否定。你只需要投票。
    • 不,这是一个哲学问题(可以这么说)。这不完全是关于否决/赞成投票,而是关于人们必须决定赞成/反对/不投票的过程和判断(部分是关于这如何影响知识较少的人的判断,他们没有多少“工具”来判断答案) .论点很广泛,完全过时了,我有时只是喜欢争论!
    猜你喜欢
    • 1970-01-01
    • 2017-01-10
    • 1970-01-01
    • 2020-07-19
    • 2014-05-28
    • 1970-01-01
    • 1970-01-01
    • 2020-09-07
    • 1970-01-01
    相关资源
    最近更新 更多