使用搜索API分析GitHub

Net::GitHub模块提供了一个用于GitHub功能丰富API的Perl接口。你可以用它做任何事情,从创建新的仓库到管理问题和发起拉取请求。今天我将关注搜索功能。

配置

获取一份Net::GitHub的副本(确保版本为0.68或更高)。CPAN测试者结果显示,它可以在包括Windows在内的所有主要平台上构建。您可以在命令行通过CPAN安装它

$ cpan Net::GitHub

第一步

首先,我们需要创建一个搜索对象。您可以匿名搜索GitHub,每分钟最多5次,或者如果您进行认证,则每分钟20次。模块文档展示了如何进行认证的示例,所以我们这里将进行非认证操作。

use Net::GitHub::V3;

# unauthenticated
my $gh = Net::GitHub::V3->new;
my $search = $gh->search;
my %data = $search->repositories({ q => 'docker'});

上面的代码创建了一个$search对象,并开始对docker进行仓库搜索。%data哈希包含了搜索结果。让我们看看它们。

{'incomplete_results' => bless( do{\(my $o = 0)}, 'JSON::XS::Boolean' ),
 'total_count' => 12830,
 'items' => [ {
                   'open_issues_count' => 771,
                   'url' => 'https://api.github.com/repos/docker/docker',
                   'has_downloads' => bless( do{\(my $o = 1)}, 'JSON::XS::Boolean' ),
                   'tags_url' => 'https://api.github.com/repos/docker/docker/tags',
                   'forks_count' => 2794,
                   'has_issues' => $VAR1->{'items'}[0]{'has_downloads'},
                   'clone_url' => 'https://github.com/docker/docker.git',
                   'name' => 'docker',
                   'private' => $VAR1->{'incomplete_results'},
                   'watchers_count' => 14846,
                   'pushed_at' => '2014-09-05T00:32:46Z',
                   'description' => 'Docker - the open-source application container engine',
                   'updated_at' => '2014-09-04T21:59:25Z',
                   'html_url' => 'https://github.com/docker/docker',
                   'stargazers_count' => 14846,
                   'size' => 135198,
                   'watchers' => 14846,
                   'created_at' => '2013-01-18T18:10:
                   'open_issues' => 771,
                   'language' => 'Go',
                   'git_url' => 'git://github.com/docker/docker.
                   'full_name' => 'docker/docker',
                   'homepage' => 'https://docker.net.cn',
                   'forks' => 2794,
                   'score' => '89.950935',
                    ...
                   },
            ]
};

为了简洁起见,我已截断结果,以显示顶级键值和简化后的一个仓库。

  • incomplete_results是一个键值对,如果搜索结果比返回的更多,则返回布尔值true。
  • total_count显示了搜索返回的仓库总数。
  • items是其中最有趣的一个 - 它是一个仓库哈希的数组引用。

获取更多结果

让我们更新代码来获取更多结果。GitHub允许每个API调用最多返回100个结果,每个搜索最多返回1,000个结果。

use Net::GitHub::V3;

my $gh = Net::GitHub::V3->new;
my $search = $gh->search;

my @data = @{ $search->repositories({ q => 'docker',
                                      per_page => 100 })->{items} };

while ($search->has_next_page) {
    sleep 12; # 5 queries max per minute
    push @data, @{ $search->next_page->{items} };
}

上面的代码执行了与之前相同的搜索,但现在我传递了per_page参数以每次调用获取100个结果。我还将items数组引用直接提取到@data数组中。while循环将继续调用搜索API,直到没有更多结果返回或达到1,000个结果的限制。

分析数据

因此,我们现在有一组完整的结果,我们可以用它做什么呢?一个可能有趣的统计分析是按编程语言计数。每个仓库哈希都包含一个language键值对,因此我们可以提取并计数它。让我们看看与Docker相关的仓库是用哪种语言编写的。

use Net::GitHub::V3;

my $gh = Net::GitHub::V3->new;
my $search = $gh->search;

my @data = @{ $search->repositories({ q => 'docker+created:>2014-09-01',
                                      per_page => 100 })->{items} };

while ($search->has_next_page) {
    sleep 12; # 5 queries max per minute
    push @data, @{ $search->next_page->{items} };
}

my %languages;

for my $repo (@data) {
    my $language = $repo->{language} ? $repo->{language} : 'Other';
    $languages{ $language }++;
}

for (sort { $languages{$b} <=> $languages{$a} } keys %languages) {
    printf "%10s: %5i\n", $_, $languages{$_};
}

让我们通过这段代码。首先,我将搜索参数更改为使用created限定符来限制结果仅限于2014年9月之后创建的仓库,以确保我们不会达到1,000个结果的搜索限制。GitHub搜索API支持一系列有用的搜索限定符(尽管没有文档说明,created将接受完整的日期时间戳,如2014-09-01T00:00:00Z)。

接下来,我声明了%languages哈希,并遍历结果,提取每个仓库的语言。如果语言是undef,则将仓库标记为“其他”。最后,我排序了结果,并使用printf打印出来,以获得格式化的输出。以下是结果:

     Shell:   238
     Other:    58
    Python:    13
      Ruby:    10
JavaScript:     8
        Go:     6
      Perl:     2
       PHP:     2
   Clojure:     1
      Java:     1

也许不出所料,结果显示在2014年9月,shell程序在Docker空间中占主导地位。

更多信息

GitHub的搜索API支持不仅仅只是仓库搜索。您还可以搜索问题、代码和用户。查看官方GitHub搜索API文档以获取更多示例。

Net::GitHub 不仅提供搜索功能,还提供了丰富的接口。您可以使用Net::GitHub通过Perl代码管理GitHub账户。开发者Fayland Lam提供了大量的文档,我发现他对询问非常乐于助人。感谢Fayland!

如果您需要的功能不仅仅是搜索,还可以看看Ingy döt Net的出色工具 git-hub,它可以在命令行上提供GitHub的全部功能。


本文最初发布在 PerlTricks.com

标签

David Farrell

David是一位职业程序员,他经常在推特博客上分享关于代码和编程艺术的见解。

浏览他们的文章

反馈

这篇文章有什么问题吗?请通过在GitHub上创建一个问题或拉取请求来帮助我们。