博客首页 注册 建议与交流 排行榜 加入友情链接
推荐 投诉 搜索: 帮助

ypxing

学而不思则罔,思而不学则殆

见贤思齐焉,见不贤而内自省也

人不知而不愠,不亦君子乎?

   ypxing.cublog.cn
关于作者  
姓名:星云鹏 (Yunpeng Xing)
职业:IT相关
年龄:28
位置:北京
个性介绍:
Love me, feed me, 
never leave me.
失败只有一种, 那就是半途而废

我的分类  




[翻译]怎样用脚本下载歌词
How to script songs lyrics retrieval

英文原文: http://www.linux.com/article.pl?sid=07/03/28/154246

我最近写了一个简单的脚本,用来把一个歌词数据库融合到我的一些音乐处理脚本中.我充分利用了开源软件的一大好处,那就是先找了一个实现该功能的程序,然后看看它源的码,来学习别人是怎么做的.

我是从学习Rhythmbox(一个音乐管理程序)的代码开始的.我发现(这个程序的)作者向一个基于Web的叫做Leo的歌词数据库发了许多简单的URL请求.请求的地址是:
http://api.leoslyrics.com/api_search.php?auth=duane&artist=cake&songtitle=comfort eagle
http://api.leoslyrics.com/api_lyrics.php?auth=duane&hid=VxwOBYpM3iY=

第 一个请求返回了一个XML文件,这个文件里包含了搜索的结果,示例如下.(服务器似乎忽略了授权信息[我用的是"duane"]. 我也没有找到关于这个网站的基于Web的 API文档.我试着以能提交歌词的账号登录该网站,然后向该网站支持的地址发送电子邮件,但仍然没有响应.)

<?xml version="1.0" encoding="UTF-8"?>
<leoslyrics>
 <response code="0">SUCCESS</response>
 <searchResults>
   <result id="120741" hid="VxwOBYpM3iY=" exactMatch="true">
     <title>Comfort Eagle</title>
     <feat/>
     <artist>
       <name>Cake</name>
     </artist>
   </result>
 </searchResults>
</leoslyrics>

从 这个response元素(<response code="0">SUCCESS</response>)来看,这次请求成功了.接下来我比较感兴起的是这个result元素 (<result id="120741" hid="VxwOBYpM3iY=" exactMatch="true">),特别是这个hid属性,它是这条歌词的id. 我把这个hid传到第二个URL中,然后得到下面这个结果:
<?xml version="1.0" encoding="UTF-8"?>
<leoslyrics>
 <response code="0">SUCCESS</response>
 <lyric hid="VxwOBYpM3iY=" id="120741">
   <title>Comfort Eagle</title>
   <feat/>
   <artist>
     <name>Cake</name>
   </artist>
   <albums>
     <album>
       <name>Comfort Eagle</name>
       <imageUrl>http://images.amazon.com/images/P/B00005MCW5.01.MZZZZZZZ.jpg</imageUrl>
     </album>
   </albums>
   <writer/>
   <text>We are building a religion
We are building it bigger
.................
Pendant keychains</text>
 </lyric>
</leoslyrics>

从这结果,我知道我可以提取出text元素 (<text>.../<text>)来得到我的歌词

我 在bash脚本里用wget和xmlstarlet来自动完成这个过程.wget是一个从Internet上以非交互的方式下载文件的小工具.我就是用 wget来请求(上面的)具有正确参数的URL来捕捉的这些XML结果的.Xmlstarlet是一组用来查询和处理XML文档的命令行工具.我用 xmlstarlet来从URL请求的结果中提取相关信息.

为了使这个脚本实用,我给这个脚本提供了一个MP3文件的路径,然后让它从这个文件的ID3标签中提取演唱者和歌名信息,用这些信息再来下载歌词.我用了id3tool,这是一个可以查看和编辑MP3文件的ID3标签的命令行工具.

在脚本的一开始运行完id3tool之后,我用sed来从id3tool的输出中提取演唱者信息,并把它存到一个叫ARTIST的shell变量中.我用类似的方法提取歌名信息.
ARTIST=`id3tool "$1" | sed -ne "s/.*Artist:\(.*\)/\1/p"`

我接着用wget来请求带有(刚才提取的)演唱者和歌名参数的URL. 请求返回的XML结果被存在一个叫做search_results的shell变量中.
search_results=`wget -q "http://api.leoslyrics.com/api_search.php?auth=$AUTH&artist=$ARTIST&songtitle=$SONGTITLE" -O -`

接着,我用xmlstarlet来解析这个XML结果.下面这个例子是执行xmlstarlet的sel命令来解析这个文本的response元素:
result=`echo $search_results | xmlstarlet sel -t -v "/leoslyrics/response/text()"`

最后,我把上面提到的技巧合起来使用(来提取歌词),再用xmlstarlet的unesc命令处理一下(unsec仅仅是用来在文本中恢复所有的转义字符,这样读起来更方便)
echo $lyrics | xmlstarlet sel -t -v "/leoslyrics/lyric/text/text()" | xmlstarlet unesc > "$1.txt"

完整的脚本一次可以下载一首个歌的歌词.如果要下载你的所有歌的歌词,你可以使用带有exec参数的find命令,来在你的所有歌曲上执行这个脚本. 例如,你的歌曲库在/share/music/目录下,你可以执行:
find /share/music/ -iname *.mp3 -exec get_lyrics.sh {} \;

你可以很容易的在你喜欢的语言里,使用同样的URL请求和结果解析技术(只要这种语言可以提取网页并能解析XML).这些技术也可以修改后用到其他支持基于Web APIs的歌词数据库中.

 原文地址 http://www.linux.com/article.pl?sid=07/03/28/154246
 发表于: 2007-04-05,修改于: 2007-04-08 18:02 已浏览877次,有评论0条 推荐 投诉

  网友评论

  发表评论



Copyright © 2001-2010 ChinaUnix.net All Rights Reserved

感谢所有关心和支持过ChinaUnix的朋友们
页面生成时间:0.20972

京ICP证041476号