Shell 操作 - 监听你的 Twitter 流

作者:Dave Taylor

上个月结束时遇到了一个非常复杂的问题,我们不得不深入研究一种不同的编程语言,以创建一个解决方案来计算地球上两个经纬度点之间的距离。我的头还在晕。我很久以前就从计算机科学专业毕业了,这到底是怎么回事?

这个月,我想我们应该回到一些更有趣,也许也更不复杂的事情(好吧,也许不是,我们拭目以待),并回到 Twitter。

我一直在思考的是,如果有一个机器人监听我的 Twitter 流,并直接回答简单的查询,而无需人工干预,那将是多么有帮助。商店可以有一个机器人来回复诸如“营业时间?”和“地址?”之类的查询,学生可以预先设置他们的课程表,机器人可以回答诸如“上课了吗?”之类的查询,以指示学生此刻正在上什么课。

事实上,在科罗拉多州博尔德市有一家本地创业公司正在朝着这个方向发展,名为 Local Bunny(localbunny.com),但它正在做一个真正的、经过深思熟虑的解决方案。相比之下,我将向您展示一种简陋的方法!

监听你的 Twitter 流

要跟踪来自个人的 Twitter 流非常容易:使用 curl 调用正确的 URL 即可完成

curl http://twitter.com/status/user_timeline/davetaylor.xml

这将为您提供我最近十几个左右的推文,以及大量附加信息,所有信息均为 XML 格式。

但是,我们想要的是提及帐户或模式,这需要您提供登录凭证。此调用有点复杂,但您仍然可以使用 curl 完成它

curl -u "davetaylor:$pw" http://www.twitter.com/statuses/mentions.xml

在这里,我将 pw 设置为我的帐户密码(您真的不想知道我的密码,对吗?)。但是,输出是另一回事。对于单个推文,返回 42 行信息(对于 140 个字符的推文)。

在这里展示太多了,但请自己尝试该命令,并对输出感到惊讶。

为了缩小范围,让我们使用 grep 和正则表达式来提取发送提及 @DaveTaylor 的推文的人的 Twitter ID 和推文本身

<text>@DaveTaylor  Have them send the money in gold bullion.</text>

  <screen_name>LenBailey</screen_name>

<text>@DaveTaylor Escrow.com</text>

  <screen_name>Ed</screen_name>

您可以在这里看到,第一条推文来自 @LenBailey,第二条来自 @Ed。

将此转化为连贯的输出有点棘手,因为我们真的想将行对合并为表示消息和 ID 的单行。这是 awk 的工作

awk '{if (NR % 2 == 1) { printf ("%s",$0) } else { print $0 }}'

现在,如果我们向其馈送 curl 输出,我们将看到

<text>@DaveTaylor  Have them send the money in gold bullion.</text>
<screen_name>LenBailey</screen_name>

<text>@DaveTaylor Escrow.com</text>  <screen_name>Ed</screen_name>

下一步:让我们摆脱 XML artifacts 并重新格式化它,使其更易于解析。我们也可以删除 @DaveTaylor,因为我们已经知道它是针对此帐户的(在实际代码中,它是一次调用,但在这里,为了清晰起见,更容易用两行显示)

sed 's/@DaveTaylor //;s/<text>//;s/<\/text>//' |
sed 's/   <screen_name>/ == /;s/<\/screen_name>//'

www.xetrade.com ?  == kiasuchick
 Have them send the money in gold bullion.  == LenBailey
Escrow.com == Ed

这样更像样了!

解析 Twitter 消息

让我们从做一些简单的事情开始。如果您使用命令 date “@”我的 Twitter 帐户,它将检测到它,实际运行 date 命令,并代表我发送结果。

为此,我们希望将数据流拆分为“tweet”和“tweeter”,但我们可以通过调整早期的 awk 字符串来创建 name=value 对,以一种巧妙的方式做到这一点

awk '{if (NR % 2 == 1) { printf ("msg=\"%s\"; ",$0) } 
 ↪else { print "id="$0 }}'

结果

msg="escrow"; id=Stepan
msg="www.xetrade.com ?"; id=kiasuchick
msg=" Have them send the money in gold bullion.  "; id=LenBailey
msg="Escrow.com"; id=Ed

不错。现在我们可以使用不断增长的脚本中未充分利用的 eval 命令将变量 msg 和 id 设置为这两个值,然后检查 msg 的已知值。现在,如果您很敏锐,您会意识到包含双引号的推文有点问题,但幸运的是,Twitter API 也很智能。所有单引号都按原样传递,但双引号被重写为 HTML 实体 &quot;。

让我们暂停一下,以便我可以向您展示我目前构建的内容

$curl -u "davetaylor:$pw" $inurl | \
  grep -E '(<screen_name>|<text>)' | \
  sed 's/@DaveTaylor //;s/  <text>//;s/<\/text>//' | \
  sed 's/    <screen_name>//;s/<\/screen_name>//' | \
  awk '{if (NR % 2 == 1) { printf ("msg=\"%s\"; ",$0) } 
   ↪else { print "id="$0 }}' >
$temp

它抓取指定用户的 20 条最新推文,并将它们转换为msg="message"id=userid对于每个推文。在循环中馈送到 eval,我们现在有一种非常简单的方法来解析事物

while read buffer
do
  eval $buffer
  echo Twitter user @$id sent message $msg
done < $temp

让我们暂时结束本专栏,但下个月,我们将采取下一步,实际解析发送给我的 Twitter “@”消息,尝试找到那些与我们设置的预定义查询匹配的消息,对其采取行动并做出回应。

当我们完成时,这将是一个非常酷的项目!

Dave Taylor 自 1980 年首次登录在线网络以来就一直参与 UNIX。这意味着,是的,他即将迎来 30 周年。您几乎可以在任何在线地方找到他,但请从这里开始:www.DaveTaylorOnline.com。除了他所有其他项目外,Dave 还是许多当地出版物的影评人。您可以在 www.DaveOnFilm.com 阅读他的评论。

加载 Disqus 评论