【问题标题】:Line by line parsing of Perl Mechanize content按线路解析Perl机械化内容
【发布时间】:2017-03-11 15:34:59
【问题描述】:

创建 perl 脚本以从各种计费网站自动下载 CSV,但由于某种原因,我无法将 $mech->content() 中的数据转换为我可以逐行解析的内容。内容为多行CSV文件,

#!/usr/bin/perl
use WWW::Mechanize;
use IO::Socket::SSL qw();

my $mech = WWW::Mechanize->new();
...stuff...
my $data=$mech->content();
my (@lines)=split(/\n?\r/,$data);
print "lines=".@lines."\n---\n@lines\n---\n";
write_file("tmp.csv",$data);

for(my $i=0;$i<@lines;$i++){
    ...work that's done that depends on each 
    line being represented as an element of 
    an array... 
}

最初我将 $mech->content() 直接分配给@lines,尝试了一些其他的东西,例如 $mech->content( raw => 1 ),正如你在上面看到的,我尝试用 \n 或 \r 拆分它. 浏览器将 csv 文件显示为 text/plain、Quirks 模式、UTF-8 运行文件 tmp.csv 显示它是 ASCII 文本并且是多行的。

我做错了什么,正确的方法是什么?

【问题讨论】:

    标签: perl www-mechanize


    【解决方案1】:

    问题出在这里:

    my (@lines)=split(/\n?\r/,$data);
    

    你有换行正则表达式向后。它是\r?\n,但对于文字字符,写\015?\012 更安全,因为\r\n 在某些系统上可能不同。

    你的 for 循环可以更好地写成:

    for my $line (@lines) {
    

    但是,您通常不希望将整个文件作为数组处理。您正在做的事情可能会占用大量内存。相反,最好先将其保存到磁盘并逐行读取 CSV 文件。

    use autodie;
    
    $mech->get( $uri, ':content_file' => "test.csv" );
    
    open my $fh, "test.csv";
    while( my $line = <$fh> ) {
        ...
    }
    

    但不要自己进行 CSV 解析。使用Text::CSV_XS 更快,错误更少。

    【讨论】:

    • 谢谢,现在我觉得很傻。这些不应该变大并且使用 Net::Google::Spreadsheets::Spreadsheet 来获取更大的文件。想要避免对 Raspberry Pi SD 进行不必要的写入。解析是反转和删除重复项。再次感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多