内容


功能丰富的 Perl

使用 Perl 增强 Twitter 实用性

学习使用 CPAN Net::Twitter 模块通过 Perl 访问 Twitter API

Comments

系列内容:

此内容是该系列 # 部分中的第 # 部分: 功能丰富的 Perl

敬请期待该系列的后续内容。

此内容是该系列的一部分:功能丰富的 Perl

敬请期待该系列的后续内容。

您可能知道 Twitter 是一项非常出色的消息传递服务,但是无法明显从中获得商业利益,它将消息长度限制在 140 字符以内,Twitter 之于技术,就如同钻石之于煤炭。Twitter 吸引人之处在于消息非常简短,人们可以很容易地关注它们。最开始的两条一般建议是:

  • 每次发出的消息的长度不能超过 139 个字符。
  • 每天发出的消息数不能超过 20 条。

违背上面这两条原则将引起人的反感,而这又必定会使您的关注者减少。

Twitter 在商业环境中也很有用。和任何消息传递服务(电子邮件等)一样,它可以用于多种用途。然而,Twitter 的商业应用通常关注 “你好,是我” 之类的消息,而不是 “有用的信息”。比如,参考 Chris Brogan 有关 Twitter 商业用途的 50 个想法(参见 参考资料);您可能也听说过 Jet Blue 和 Dell 的成功示例。

本文探讨自动化 Twitter 发布和搜索,这些特性对企业的意义要远远大于对在 Twitter 上发帖以寻求业务的个人。从技术上来说,后者并不是很有趣。(但是使用一个 API 假扮人类并对 Twitter 发帖作出响应会非常吸引人)。

您应当已经知道了如何安装 CPAN 模块(具体来讲就是 Net::Twitter),但是本文面向的是初级 Perl 程序员。如果需要 CPAN 帮助,请参见 参考资料 部分。

最后,我没有使用 “tweets” 指代 Twitter 中的发帖,除非 API 语言强制要求这样做。如果您喜欢 “tweets” 一词的话,那么很抱歉;我只是觉得避免使用该词会让本文更清晰。

前言太长了;让我们开始构建应用程序吧。

我们的目标

我们将传播什么类型的信息?让我们构想一个使用 Perl 但是不希望使用 Twitter 的公司,因为他们在新闻中听说过它;他们衡量过其他选项,然后谨慎选择了 Twitter,并仔细考虑过要发布的内容。

该公司的名称为 The Cultured Perl, Ltd,并且他们在 http://twitter.com/cultured_perl 下创建了一个 Twitter 帐户。

想象一下这有多么激动人心吧。在 Twitter 中开展业务,既不会违背法律,同时还能获得广泛的市场。作为首席开发人员,您希望完成工作任务,因此决定在 Twitter 上尝试两件事情,看看它的表现如何,并且不用考虑任何麻烦的问题。

首先,在 Twitter 中搜索有关 “perl” 的内容,看看人们正在讨论哪些有关 Perl 的有趣内容,这也许可以为公司提供有关产品的灵感。

其次,您将为招聘声明设置自动发帖功能(您也考虑了解雇声明,但是否决了这个想法,因为觉得这样做不太合适)。

在 Twitter 中搜索关键字

Twitter 是一种非常易于使用的服务。公司在运行该服务时必须考虑所有细节 — 服务利用率、网络费用、坏掉的硬盘驱动器等等。您打开一个 TCP/IP 连接,提出一个问题,然后返回一个答案。这是基于 Web 的服务的特征,并且对用户有利,但是最好记住一点,如果反复执行的话,关键字搜索在服务器端会产生很大的开销(如果关键字总是变化的话尤其如此)。除非绝对必要,否则不要使用自动化查询来损耗 Twitter 的服务器。

twitter_do.pl 脚本将执行 Twitter 搜索和发布(twitter_do.pl 将在下一节介绍并包含在 下载 小节中)。注意,您不需要密码就可以执行搜索,但是需要使用密码发帖。

twitter_do.pl 脚本使用 Getopt::Long 获得命令行参数,如 usage() 函数描述的一样。脚本使用一个帮助屏幕,使用户能够自己找到选项。

注意它如何使用 --verbose 选项,每个选项的快捷方式,以及搜索结果的详细输出如何将未定义字符串表示为 (UNDEFINED),而不是仅仅忽略它们。这些都是可以让用户一直感到愉快的小细节。

清单 1. twitter_do.pl: Nice 使用帮助
sub usage
{
 return <<EOHIPPUS

 $0 [OPTIONS] SEARCH1 [SEARCH2 ...]

Note that you can search without a valid login.

Options:
 --help or -h                    : this help
 --verbose or -v                 : print more verbose output
 --rpp=100 or -r 100             : 100 results per page
 --maxresults=100 or -n 100      : return at most 100 search matches
 --popularity or -y              : analyze user popularity for search results
 --post=NEWS or -o NEWS          : post on Twitter
 --username=NAME or -u NAME      : specify the Twitter username
 --passwordfile=FILE or -pf FILE : specify a file that contains
                                   the Twitter password
 --password=PASS or -p PASS      : specify the Twitter password
EOHIPPUS
}

Twitter 搜索结果以一个散列引用的方式返回,除搜索结果本身外,还包含一个页面计数和其他字段。我们只获取结果,将它们添加到结果的完整列表中,然后执行另一次搜索(显示结果的下一个页面),直到我们获得足够多的结果(根据 --maxresults 选项),或是没有获得任何结果。结果已经根据日期进行了排序,因此我们可以保持目前的顺序。

不幸的是,我们无法计算结果的数量,我们必须遍历每一个页面,引起 Twitter 对搜索词的多次不必要的点击。可以使用 --rpp 选项改变这一情况。类似地,如果我们获得比 --maxresults 更多的结果:

清单 2. 按关键字搜索 Twitter
sub do_search
{
 my $term = shift @_;

 my $page = 1;
 my @results;

 while (scalar @results < $opts{maxresults})
 {
  my $rset = $handle->search({query=>$term, page => $page, rpp => $opts{rpp} });
  print "Searching for $term (page $page)\n" if $opts{verbose};
  if (ref $rset eq 'HASH' && exists $rset->{results})
  {
   # break out if no results came back
   last unless @{$rset->{results}};
   push @results, @{$rset->{results}};
   printf "Now we have %d entries\n", scalar @results if $opts{verbose};
  }

  # go to the next page
  $page++;
 }

 print_post($_) foreach @results;
}
清单 3. 输出搜索匹配
sub print_post
{
 my $t = shift @_;
 
 printf("%s (on %s)\n\t%s\n", $t->{from_user}, $t->{created_at}, $t->{text});

 if ($opts{verbose})
 {
  foreach my $key (sort keys %$t)
  {
   my $v = $t->{$key};
   $v = '(UNDEFINED)' unless defined $v;
   print "...$key=$v\n";
  }
 }
}

print_post 函数没有什么有趣的内容,因此让我们休息一会,放松一下。现在喝些提神的饮料,因为我们要开始讨论发帖了。

在 Twitter 上发帖

我们将在脚本中使用一个密码文件命令行选项。可以将密码放到文件中并使用 -pf 选项指定它,或者直接使用 -p 指定选项。为了安全起见,最好使用第一种方法,但是后一种方法更方便些。

清单 4. 在 Twitter 上发帖:密码选项
if (exists $opts{passwordfile} && !exists $opts{password} )
{
 open PF, "<", $opts{passwordfile} 
  or die "Couldn't open $opts{passwordfile}: $!";
 $opts{password} = <PF>;
 close PF;
 chomp $opts{password};
}

# require the password AND at least one search term OR a post
die usage() 
 unless (defined $opts{password} && exists $opts{post}) || scalar @ARGV;

令人烦恼的是,包含空格的密码是无效的。使用在 URL 中有效的字符(字母、数字、横线、下划线:[A-Za-z0-9_-])。

发帖以后,我们将检查最新帖子中是否包含与我们将要发布的内容相同的文本。很简单,对不对?

清单 5. 在 Twitter 上发帖:文本检查
sub do_post
{
 my $post = shift @_;

 $post = '(UNDEFINED)' unless defined $post;
 my $ret = $handle->update({status => $post});
 warn "Could not post the update" unless defined $ret;
 if ($ret->{text} eq $post)
 {
  print "Successfully posted [$post].\n";
 }
 else
 {
  warn "Posted string [$ret->{text}] is different from given [$post]";
 }
}

将发帖命令与公司的职位数据库连接起来非常简单:执行一个快速的 SQL 查询(类似 SELECT desc,salary FROM jobs WHERE created > yesterday AND salary NOT NULL AND desc LIKE '%perl%' 的查询,这是一虚构的 SQL),结果将会出现在 twitter_do.pl 中。

分析 Twitter 搜索结果

Cultured Perl, Ltd. 的以 Twitter 为中心的新战略获得了巨大成功。他们在短短几天内聘用了三名人员并获得 1,800 名关注者— 做的漂亮!

但是,您觉得还可以做得更好。您决定分析搜索结果来评估 Perl 的流行度。方法为查找前 1,000 个搜索匹配,找到发布这些帖子的用户,然后衡量这些用户的受欢迎度。受欢迎度的计算方式为好友数的一半加上关注者人数的两倍(但是可以根据具体目标调整计算公式)。使用不成比例的权重是因为在 Twitter 上关注其他人要比被别人关注容易得多。

为此,使用 Net::Twitter::friends_ids()Net::Twitter::followers_ids()。衡量受欢迎度的功能的挂钩被放在非常繁琐的 print_post() 函数中,这样会让它更有趣一些。新版本函数将有一个范围有限的散列(scoped hash),表示只有该函数可以直接访问散列,并且持续到每个调用中,因此将是一个很好的缓存。该缓存允许存储受欢迎度,因此避免了反复调用开销较高的方法。

清单 6 展示了新版本的 print_post()。全局选项也需要进行调整以实现 --popularity 转换,并且使用文本也被调整(清单 1 包含更新后的文本)。

清单 6. 根据搜索词轻松地分析 Twitter 受欢迎度
{
 # this hash is scoped to the print_post function only
 my %popularity;			

 sub print_post
 {
  my $t = shift @_;
  
  printf("%s (on %s)\n\t%s\n", $t->{from_user}, $t->{created_at}, $t->{text});
  
  if ($opts{verbose})
  {
   foreach my $key (sort keys %$t)
   {
    my $v = $t->{$key};
    $v = '(UNDEFINED)' unless defined $v;
    print "...$key=$v\n";
   }
  }

  if (exists $opts{popularity})
  {
   my $user = $t->{from_user};
   unless (exists $popularity{$user})
   {
    $popularity{$user} = scalar @{$handle->friends_ids($user)}/2 + 
    		         2* scalar @{$handle->followers_ids($user)};
   }

   print "\n\tPOPULARITY for $user = $popularity{$user}\n";

   my $sum = 0;
   $sum += $_ foreach values %popularity;
   
   printf "\tAVERAGE POPULARITY = %.2f\n", $sum / scalar keys %popularity;
  }
 }
}

为了简明易懂,每次分析都计算并输出平均值,但是可以很容易地将这些功能移出到循环以外。运行 ./twitter_do.pl -n 10 -y perl 并循环到 1,000,如果您确定需要这么做的话。

结束语

您了解了 Twitter 中的发布和搜索功能。本文演示了每一个功能的完整可用示例,并集成到一个单一脚本中,以简化选项和其他包装器的处理。

最后,您了解了如何通过使用用户的好友数和关注者数来衡量某个用户在 Twitter 上的受欢迎度。

还可以通过许多途径来使用 Twitter。本文提供了一些通过 Perl 代码展示的实用的建议和想法,希望给您以启发。请一定要查看 Net::Twitter 文档和 Twitter API wiki,看看利用这项服务还可以做些什么。


下载资源


相关主题


评论

添加或订阅评论,请先登录注册

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=Linux, Open source, Web development
ArticleID=460194
ArticleTitle=功能丰富的 Perl: 使用 Perl 增强 Twitter 实用性
publish-date=01042010