当前位置: 首页 >> 程序设计 >> 脚本编程实现自动下载歌词
 

脚本编程实现自动下载歌词

作者:      来源:ypxing.cublog.cn     发表时间:2007-04-06     浏览次数:      字号:    

英文原文: 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

责任编辑 webmaster

 
 
 
 
 
评论更多>>
 
 
 
发表
 
姓名: QQ:
性别: MSN:
E-mail: 主页:
评分: 1 2 3 4 5
评论内容:
验证码:
  
  • 请遵守《互联网电子公告服务管理规定》及中华人民共和国其他各项有关法律法规。
  • 严禁发表危害国家安全、损害国家利益、破坏民族团结、破坏国家宗教政策、破坏社会稳定、侮辱、诽谤、教唆、淫秽等内容的评论 。
  • 用户需对自己在使用本站服务过程中的行为承担法律责任(直接或间接导致的)。
  • 本站管理员有权保留或删除评论内容。
  • 评论内容只代表网友个人观点,与本网站立场无关。
  •