在 Perl 中获取 JSON
Fetching JSON in Perl
我一直在用 Perl 构建模拟器,我面临的问题之一是解析计算机中的 JSON 文件。当我尝试从我的服务器获取它们时,它们工作正常...
method getContent(\@arrURLS) {
my %arrInfo;
my $resUserAgent = Mojo::UserAgent->new;
foreach my $strURL (@arrURLS) {
$resUserAgent->get($strURL => sub {
my($resUserAgent, $tx) = @_;
if ($tx->success) {
my $strName = basename($strURL, '.json');
my $arrData = $tx->res->body;
$arrInfo{$strName} = $arrData;
}
Mojo::IOLoop->stop;
});
Mojo::IOLoop->start;
}
return \%arrInfo;
}
我们假设 @arrURLS
是:
my @arrURLS = ("file:///C:/Users/Test/Desktop/JSONS/first.json", "file:///C:/Users/Test/Desktop/JSONS/second.json");
上面的 url 是行不通的,但是如果我将其更改为:
my @arrURLS = ("http://127.0.0.1/test/json/first.json", "http://127.0.0.1/test/json/second.json");
有效。
另外我想使用比 Mojo::UserAgent
更好的东西,因为它看起来有点慢,当我使用 Coro
和 LWP::Simple
时它要快得多但不幸的是 Coro
在 Perl 5.22 中被破坏...
User Agent主要是通过http下载文件。通常不希望它们处理文件系统 URI。您需要 open
and read the file yourself, or use a module like File::Slurp 为您完成。
它可能看起来像这样。
use File::Slurp 'read_file';
method getContent(\@arrURLS) {
my %arrInfo;
my $resUserAgent = Mojo::UserAgent->new;
foreach my $strURL (@arrURLS) {
if (substr($strURL, 0, 4) eq 'file') {
$arrInfo{basename($strURL, '.json')} = read_file($strURL);
} else {
$resUserAgent->get($strURL => sub {
my($resUserAgent, $tx) = @_;
if ($tx->success) {
my $strName = basename($strURL, '.json');
my $arrData = $tx->res->body;
$arrInfo{$strName} = $arrData;
}
Mojo::IOLoop->stop;
});
Mojo::IOLoop->start;
}
}
return \%arrInfo;
}
我自己使用 WWW::Mechanize 完成所有此类任务。来自文档:
WWW::Mechanize is a proper subclass of LWP::UserAgent and you can also
use any of LWP::UserAgent's methods.
这意味着您也可以使用 file://
类型的 URL 来提供它。
例如,以下一行转储您的 passwd
文件。
perl -MWWW::Mechanize -E 'say WWW::Mechanize->new->get("file://etc/passwd")->content'
或者没有任何错误处理的例子...
use 5.014;
use warnings;
use WWW::Mechanize;
my $mech = WWW::Mechanize->new;
$mech->get('file://some/path');
say $mech->content;
无论如何,对本地文件使用一些 file-based
实用程序可能更好,我自己对所有文件使用 Path::Tiny 模块,它具有(不仅限于)文件 slurping 方法,例如:
use Path::Tiny;
my $content = path('/some/path')->slurp;
或者只是简单的 perl:
open my $fh, '<', '/some/file' or die "...";
my $content = do { local $/; <$fh> };
close $fh;
请务必说明您正在使用哪些附加模块。我认为您的代码使用 Method::Signatures
,并且我测试了下面的代码只是为了检查它是否使用该模块进行编译
Mojolicious 是一款出色的工具,但它专注于 HTTP URL。 LWP::UserAgent
is much more general-purpose, and the documentation for LWP
这么说
Provides an object oriented model of HTTP-style communication. Within this framework we currently support access to http, https, gopher, ftp, news, file, and mailto resources
你的方法变成了这样。未经测试
method get_content(\@urls) {
my %info;
my $ua = LWP::UserAgent->new;
for my $url (@urls) {
my $res = $ua->get($url);
die $res->status_line unless $res->is_success;
my $name = basename($url) . '.json';
my $data = $res->decoded_content;
$info{$name} = $data;
}
\%info;
}
我还鼓励您在 Perl 代码的上下文中放弃匈牙利符号,因为该语言已经具有表示数据类型的标志
@arrURLS
复制了这个 arrURLS
是一个数组的信息,而 %arrInfo
是错误的,因为这个 arrInfo
是一个 哈希 。 $arrData
实际上是一个 标量 ,尽管也许一些指示它也是 参考 的指标可能会有所帮助,而 $arrURLS[0]
是也是一个 标量(因此是美元)
也没有什么可以阻止您使用 $arrURLS
(这是一个完全独立于 @arrURLS
的变量)
我一直在用 Perl 构建模拟器,我面临的问题之一是解析计算机中的 JSON 文件。当我尝试从我的服务器获取它们时,它们工作正常...
method getContent(\@arrURLS) {
my %arrInfo;
my $resUserAgent = Mojo::UserAgent->new;
foreach my $strURL (@arrURLS) {
$resUserAgent->get($strURL => sub {
my($resUserAgent, $tx) = @_;
if ($tx->success) {
my $strName = basename($strURL, '.json');
my $arrData = $tx->res->body;
$arrInfo{$strName} = $arrData;
}
Mojo::IOLoop->stop;
});
Mojo::IOLoop->start;
}
return \%arrInfo;
}
我们假设 @arrURLS
是:
my @arrURLS = ("file:///C:/Users/Test/Desktop/JSONS/first.json", "file:///C:/Users/Test/Desktop/JSONS/second.json");
上面的 url 是行不通的,但是如果我将其更改为:
my @arrURLS = ("http://127.0.0.1/test/json/first.json", "http://127.0.0.1/test/json/second.json");
有效。
另外我想使用比 Mojo::UserAgent
更好的东西,因为它看起来有点慢,当我使用 Coro
和 LWP::Simple
时它要快得多但不幸的是 Coro
在 Perl 5.22 中被破坏...
User Agent主要是通过http下载文件。通常不希望它们处理文件系统 URI。您需要 open
and read the file yourself, or use a module like File::Slurp 为您完成。
它可能看起来像这样。
use File::Slurp 'read_file';
method getContent(\@arrURLS) {
my %arrInfo;
my $resUserAgent = Mojo::UserAgent->new;
foreach my $strURL (@arrURLS) {
if (substr($strURL, 0, 4) eq 'file') {
$arrInfo{basename($strURL, '.json')} = read_file($strURL);
} else {
$resUserAgent->get($strURL => sub {
my($resUserAgent, $tx) = @_;
if ($tx->success) {
my $strName = basename($strURL, '.json');
my $arrData = $tx->res->body;
$arrInfo{$strName} = $arrData;
}
Mojo::IOLoop->stop;
});
Mojo::IOLoop->start;
}
}
return \%arrInfo;
}
我自己使用 WWW::Mechanize 完成所有此类任务。来自文档:
WWW::Mechanize is a proper subclass of LWP::UserAgent and you can also use any of LWP::UserAgent's methods.
这意味着您也可以使用 file://
类型的 URL 来提供它。
例如,以下一行转储您的 passwd
文件。
perl -MWWW::Mechanize -E 'say WWW::Mechanize->new->get("file://etc/passwd")->content'
或者没有任何错误处理的例子...
use 5.014;
use warnings;
use WWW::Mechanize;
my $mech = WWW::Mechanize->new;
$mech->get('file://some/path');
say $mech->content;
无论如何,对本地文件使用一些 file-based
实用程序可能更好,我自己对所有文件使用 Path::Tiny 模块,它具有(不仅限于)文件 slurping 方法,例如:
use Path::Tiny;
my $content = path('/some/path')->slurp;
或者只是简单的 perl:
open my $fh, '<', '/some/file' or die "...";
my $content = do { local $/; <$fh> };
close $fh;
请务必说明您正在使用哪些附加模块。我认为您的代码使用 Method::Signatures
,并且我测试了下面的代码只是为了检查它是否使用该模块进行编译
Mojolicious 是一款出色的工具,但它专注于 HTTP URL。 LWP::UserAgent
is much more general-purpose, and the documentation for LWP
这么说
Provides an object oriented model of HTTP-style communication. Within this framework we currently support access to http, https, gopher, ftp, news, file, and mailto resources
你的方法变成了这样。未经测试
method get_content(\@urls) {
my %info;
my $ua = LWP::UserAgent->new;
for my $url (@urls) {
my $res = $ua->get($url);
die $res->status_line unless $res->is_success;
my $name = basename($url) . '.json';
my $data = $res->decoded_content;
$info{$name} = $data;
}
\%info;
}
我还鼓励您在 Perl 代码的上下文中放弃匈牙利符号,因为该语言已经具有表示数据类型的标志
@arrURLS
复制了这个 arrURLS
是一个数组的信息,而 %arrInfo
是错误的,因为这个 arrInfo
是一个 哈希 。 $arrData
实际上是一个 标量 ,尽管也许一些指示它也是 参考 的指标可能会有所帮助,而 $arrURLS[0]
是也是一个 标量(因此是美元)
也没有什么可以阻止您使用 $arrURLS
(这是一个完全独立于 @arrURLS
的变量)