【问题标题】:Twitch TMI, extract all usersTwitch TMI,提取所有用户
【发布时间】:2017-12-17 21:11:51
【问题描述】:

我正在尝试从源 (https://tmi.twitch.tv/group/user/twitchpresents/chatters) 中提取所有用户名,但到目前为止我只能得到第一个“名称”。 目标是将所有名称放入一个数组中,然后只删除“viewers”、“admins”、“staff”等名称。

use strict;
use warnings;

my @listusers = userlist();
sub userlist {
    my $url = "https://tmi.twitch.tv/group/user/twitchpresents/chatters";
    my $array = get($url);
    my @array2;
    my $time = 0;

    while ($time != 2){
       my $mylist = (join "",grep(/"\s*(.*?)\s*"/, $array[$time])) =~ /"\s*(.*?)\s*"/;
       print $1;
       $time++;
    }
    return @array2;

}

print @listusers;

【问题讨论】:

  • 哦,我明白了。你应该在循环内push(@array2, $1)。而且,$mylist 只获取匹配结果 bool。因此,如果是 $mylist,则打印并存储 $1。
  • 这是有效的 JSON - 所以恕我直言,最好使用一些 JSON 解析器。
  • 此代码不会像发布的那样编译。 $array[$time] 应该是 $array->[$time],因为它是一个数组引用。然后:为什么要返回一个数组@array2,如果它没有任何内容?或者,相反,如果您返回my @array2,为什么还要执行所有这些代码:P。最重要的是:是的,请使用 JSON 解析器。

标签: regex perl extract text-mining twitch


【解决方案1】:

我假设您从LWP::Simple 获得带有get 的页面。请始终显示相关的包含。

由于这是有效的 JSON,请为此使用模块

use warnings;
use strict;
use feature 'say';
use Data::Dump qw(dd);

use LWP::Simple;    
use JSON;

my $data_json = get($url);

my $data = JSON->new->decode($data_json);
#dd $data;

my @names = @{ $data->{chatters}{moderators} };             # get "moderators"
say "@names";
# my @all_names = map { @$_ } values %{$data->{chatters}};  # or get all names

这将打印以下行:cliccer cuda hnlbot nixi93 scorpy0 somppe

我打印出版主的“名字”,作为排除一个类别的例子;注释掉的行将所有名称放在一个数组中。一旦你有了一个 hashref,就有多种方法可以提取你需要的东西。

您的代码似乎正在尝试解析该 JSON 字符串。使用模块很容易。

可以使用Data::Dumper 等查看复杂的数据结构。我用Data::Dump

这里使用了JSON,如果已安装,则委托给JSON::XS,否则委托给“纯Perl”(和更慢的)JSON::PP。另一个选项是Cpanel::JSON::XS


为了方便,dd $data打印出来的结构是

{ _links => {}, chatter_count => 15, 喋喋不休=> { 管理员 => [], global_mods => [], 版主=> [ “剪贴画”, “库达”, “hnlbot”, “joffy95”, "nixi93", “蝎子0”, “松柏”, ], 工作人员 => [], 观众 => [ “冷血94”, “冷机器人”, “gabenator”, “加罗克”, “reconcrusadershadow”, “擦洗”, "shai_the_panda", “奏鸣曲”, ], }, }

【讨论】:

  • 或使用ojo:perl -Mojo -E 'my $d=j( g(q{https://tmi.twitch.tv/group/user/twitchpresents/chatters})->body );say "@$_" for @{$d->{chatters}}{qw(moderators viewers)}'
  • @jm666 当然 :) 但他们选择了LWP::Simple,所以我保留了这种方法
【解决方案2】:

我建议您使用 Mojo::UserAgent 为此,它包含一个 JSON 解码器以及一个 HTTP 用户代理,并使代码更加简洁

我假设您想要 chatters 的所有不同类别的名称,这就是 map 语句的作用:简单地展平所有类别 —adminsglobal_mods、@987654326 @、staffviewers——合并到一个列表中

如果 HTTP 传输出现任何问题,则子例程将简单地返回一个空列表,因此您可能需要添加一些适当的错误处理

use strict;
use warnings;
use feature 'say';

use Mojo::UserAgent;

my @list_users = chatters();
say for @list_users;

sub chatters {

    my $url = 'https://tmi.twitch.tv/group/user/twitchpresents/chatters';
    return unless my $data = Mojo::UserAgent->new->get($url)->res->json;

    map { @$_ } values %{ $data->{chatters} };
}

输出

girlonduty
moobot
ravager
100tesports
123mickeypr
13eebo
13urnxcalibur
2dmoody
2l33t
2tony79
3nticed
...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-18
    • 2022-08-19
    • 1970-01-01
    • 2021-09-07
    相关资源
    最近更新 更多