Shell 技巧 - 关于电影、知识问答游戏和 Twitter
在过去的几个月里,我成了一个瘾君子。事实上,我从一个怀疑论者变成了一个福音传道者,这种转变可能使我成为 12 步康复计划的典型案例。这个吞噬我的大脑和热情的邪恶东西是什么呢?它不是非法的;它不是我必须对孩子们隐瞒的东西;但是,是的,它非常 Geek,并且它是 Web 2.0 宇宙中增长最快的服务之一:Twitter。
我发现 Twitter 最引人入胜的地方在于它既流行又新兴,因此,你可以亲眼看到它的最佳实践在不断演变。即使在我使用这项服务的几个月里,它也从仅仅是个人更新(例如“在麦当劳吃汉堡。30 分钟后回去开会”)发展到更多的商业用途和新闻传播(“快讯:Redbox 被读卡器黑客入侵。请看...”)。
简而言之,Twitter 允许您向数十、数百甚至数千名关注者发送非常短的消息,从 Linux/shell 脚本的角度来看,它非常酷,因为 API 允许您用一行代码轻松发送消息。但是,我们稍后会讲到这一点。首先,我们需要一些东西来传输。
因为我似乎无法摆脱对编写 shell 脚本游戏的enthusiasm(说到心理学上的好奇心,这又是另一个),我认为为 Twitter 编写一个电影知识问答游戏会很有趣。所以,这就是我们要做的。
挑战在于弄清楚数据将从何而来。我的意思是,我为 etymologic.com 构建了一个庞大的词汇历史知识数据库,我的朋友 Kevin Savetz 和我为 trivial.net 编写了 500 多个计算机知识问答题,这是一项巨大的工作量。自从创建这些网站以来,我变得太懒惰以至于无法重复这项工作,所以问题是找到一个我可以利用或重新利用现有电影信息的地方,这些信息将有助于知识问答游戏。
为了这次努力,我将使用互联网电影数据库 (www.imdb.com),它在其数据库深处拥有大量的有趣电影知识。一个开始的地方是它的随机电影引言功能,网址是 www.imdb.com/Games/randomquote.html,但说实话,这些知识非常晦涩难懂,我从来没有认出任何引言,而我是一个十足的电影迷。
让我们把事情弄得更复杂一些,从 IMDb 前 250 名电影列表开始,并从这些电影中隔离引言和知识。该列表位于 www.imdb.com/chart/top,如果你打开它,你会看到每部电影都以这种形式的 URL 引用 http://www.imdb.com/title/tt0068646/。
这意味着一个简单的 grep 可以提取前 250 名电影中每一部的 URL。利用 curl,这就是你所需要的一切
curl -s http://www.imdb.com/chart/top | \ sed 's/</\ /g' | grep '/title/tt' | more
输出结果不太符合我们的要求,但它已经非常接近一个可用的数据库了,仅凭这个简单的命令,甚至不足以证明 shell 脚本的合理性
a href="/title/tt0068646/">The Godfather a href="/title/tt0111161/">The Shawshank Redemption a href="/title/tt0071562/">The Godfather: Part II a href="/title/tt0060196/">Buono, il brutto, il cattivo, Il a href="/title/tt0110912/">Pulp Fiction
为了只提取我们需要的东西,因为我们真正想要的只是一个包含前 250 名电影的 250 个 URL 的文件,我们只需要添加一个小的补充
curl -s http://www.imdb.com/chart/top | sed 's/</\ /g' | grep '/title/tt' | cut -d\" -f2
这就是结果
/title/tt0068646/ /title/tt0111161/ /title/tt0071562/ /title/tt0060196/ /title/tt0110912/ ...many, many lines skipped... /title/tt0325980/ /title/tt0061809/ /title/tt0113247/
很容易将所有这些都放入一个数据文件中,像这样简单地调用 sed 来修复 URL,使它们成为完全限定的 URL
| sed 's/^/http:\/\/www.imdb.com/'
现在我们有一个包含 URL 的数据文件,像这样
http://www.imdb.com/title/tt0068646/
访问这个 URL,你会发现它是 IMDd 上的头号电影,精彩的电影 The Godfather。
好的,所以我们已经弄清楚了如何根据 IMDb 投票者获得前 250 名电影的列表,但问题是,“在这一点上,我们如何获得有用的信息?” 答案是访问每个页面并抓取其上的内容。
看看 The Godfather 的页面,一个简单的知识问答游戏立刻浮现在脑海:一部特定的热门电影是哪一年上映的?
这可以通过简单地抓取页面的标题来完成,而页面的标题恰好是电影名称和上映年份
curl -s http://www.imdb.com/title/tt0068646/ | grep '<title>'
它不太符合我们的要求,但非常接近了
<title>The Godfather (1972)</title>
它足够接近,我们现在可以编写一个简短的脚本,该脚本接受 IMDb 电影标题 URL 并输出电影名称,后跟一个管道符号(一个方便的字段分隔符)和电影上映的年份
#!/bin/sh # given an IMDb film URL, output title & release year curl -s "$1" | \ grep '<title>' | cut -d\> -f2 | cut -d\< -f1 | \ sed 's/([0-9][0-9][0-9][0-9])/| &/' | sed 's/(//;s/)//' exit 0
(复杂的 sed 正则表达式是为了确保我们不仅仅匹配左括号,以防电影标题包含括号。)
有了这个脚本,我们现在可以简单地将列表倒入脚本中,并提取前十名电影的快速列表
for name in $(cat top250.txt) do ./get-film-info.sh $name done | head -10
这就是输出结果
The Godfather | 1972 The Shawshank Redemption | 1994 The Godfather: Part II | 1974 Buono, il brutto, il cattivo, Il | 1966 Pulp Fiction | 1994 Schindler's List | 1993 One Flew Over the Cuckoo's Nest | 1975 Star Wars: Episode V - The Empire Strikes Back | 1980 Casablanca | 1942 Shichinin no samurai | 1954
酷。现在我们取得了一些进展。让我们在这里停下来,下个月,我将研究从 250 个条目中提取一个随机条目,然后生成三个在数值上接近正确年份的随机数字,并将所有四个数字作为问题“XX 是哪一年上映的?”的可能答案。
现在,我想我会把 Casablanca 放入我的蓝光播放器中放松一下,而 Linux Journal 团队则在努力排版。再见,shweetheart。
Dave Taylor 是 UNIX 领域 26 年的资深人士,The Elm Mail System 的创建者,也是畅销书 Wicked Cool Shell Scripts 和 Teach Yourself Unix in 24 Hours 的作者,以及他的 16 本技术书籍。他的主要网站是 www.intuitive.com,他还通过 AskDaveTaylor.com 提供技术支持。如果您愿意,请在 Twitter 上关注他:twitter.com/DaveTaylor。