美文网首页
shell爬虫批量下载mp3

shell爬虫批量下载mp3

作者: uuspider | 来源:发表于2018-03-04 00:59 被阅读160次

最近喜欢听王玥波的《雍正剑侠图》,搜到某网站上有全套,可惜,只能一回一回地手动下载,现在出到了第六部,每一部都有上百回,手动点鼠标下载得下到猴年马月去了。古人说:“Where there is a shell, there is a way”,用shell脚本来做这件事吧。

Where there is a shell, there is a way.

shell脚本由linux命令组合而成,由于linux现有的大量命令工具都经过了长期的优化和标准化,其执行效率和移植性都很高。

shell爬虫的核心是curlcurl可以下载网页,解析http response头信息,也可以指定http request头信息,且可处理cookie,具备web浏览器的基本功能,支持HTTPS、FTP、FTPS、TELNET、LDAP等协议。

强大的curl

首先,是解析每一回音频的url,每一回对应一个链接页面,地址的编排很简单,如第一回就是:

http://xxx.com/play/5359/1.html

想当然地使用chrome查看音频的加载过程,结果发现音频文件的url直接写在了源码里:

<a href="http://xxx.com/%E7%8E%8B%E7%8E%A5%E6%B3%A2/%E9%9B%8D%E6%AD%A3%E5%89%91%E4%BE%A0%E5%9B%BE%E7%AC%AC%E4%BA%94%E9%83%A8%2832kbps%29%28121%E5%9B%9E%29/03BEE21D25.mp3" id='down'><img src="//xxx.com/e/data/images/download.jpg" alt="下载雍正剑侠图第五部 001回"></a>

而且该网页中只有这一行出现了.mp3,不过文件名是随机生成的。

每一回的url有了,这就好办了,先把核心功能完成:

#!/usr/bin/env bash

page_url='http://xxx.com/down/5359/'

for ((i=1; i<=121; i++))
do
    page_i="${page_url}$i.html"
    mp3_i_url=$(curl ${page_i} | iconv -c -f gb2312 -t utf-8 | grep '\.mp3' | awk -F\" '{print $2}')
    curl -o "$i.mp3" ${mp3_i_url}
done

exit 0

下面来逐行分析一下for循环究竟做了什么。

$page_i是第i回的下载页面,不过并不是下载链接,下载链接$mp3_i_url需要解析出来。

curl ${page_i}

获取该页面的html代码,该页面编码是GB2312,标准输出的汉字是乱码,如不进行处理可能会导致脚本执行中报错退出,因此使用iconv进行转码:

iconv -c -f gb2312 -t utf-8

将网页编码从gb2312转为utf-8,选项-c表示忽略转码过程中的报错,以避免脚本意外中止。

grep '\.mp3'

使用grep查找含有'.mp3'的行,这里使用了转义符'\'。

awk -F\" '{print $2}'

这是截取mp3文件的下载链接,awk是一个强大的工具,可以将一行文本分解为多列进行处理,这里指定"为分割符,将这行原代码:

<a href="http://xxx.com/%E7%8E%8B%E7%8E%A5%E6%B3%A2/%E9%9B%8D%E6%AD%A3%E5%89%91%E4%BE%A0%E5%9B%BE%E7%AC%AC%E4%BA%94%E9%83%A8%2832kbps%29%28121%E5%9B%9E%29/03BEE21D25.mp3" id='down'><img src="//xxx.com/e/data/images/download.jpg" alt="下载雍正剑侠图第五部 001回"></a>

分解为7列:

<a href=

http://xxx.com/%E7%8E%8B%E7%8E%A5%E6%B3%A2/%E9%9B%8D%E6%AD%A3%E5%89%91%E4%BE%A0%E5%9B%BE%E7%AC%AC%E4%BA%94%E9%83%A8%2832kbps%29%28121%E5%9B%9E%29/03BEE21D25.mp3

 id='down'><img src=

//xxx.com/e/data/images/download.jpg

 alt=

下载雍正剑侠图第五部 001回

></a>

我们需要的链接是第二列,使用{print $2}将该列赋值给$mp3_i_url

curl -o "$i.mp3" ${mp3_i_url}

再次使用curl,下载mp3文件,并重命名为$i.mp3,完成第i回的下载任务。

以上代码已经达到了我们的目的,不过考虑到网站可能采取的反爬措施,再加几行:

#!/usr/bin/env bash

page_url='http://xxx.com/down/5359/'

user_agent='Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.130 Safari/537.36'

for ((i=1; i<=121; i++))
do
    page_i="${page_url}$i.html"
    mp3_i_url=$(curl -A ${user_agent} ${page_i} | iconv -c -f gb2312 -t utf-8 | grep '\.mp3' | awk -F\" '{print $2}')
    curl -A ${user_agent} -o "$i.mp3" ${mp3_i_url}
    sleep 30
done

exit 0

主要做了两种反反爬措施,一是下完一回后延时30s,这个比较好理解。

二是使用curl-A选项,在request中指定User-Agent字段,用于模拟客户端设备和浏览器:

curl -A ${user_agent} ${page_i}

不过后来发现,该网站的反爬措施好像并不完善。

到此为止,脚本已经完成,丢到Raspberry pi上去跑了一晚,第二天早上,成功收获了热热乎乎的《雍正剑侠图》。

运行效果

对于简单的爬虫功能,和python相比,shell的代码量显然更少,写起来也更快,毕竟这东西基本上只是一次性的,杀鸡还是不要动牛刀了。

相关文章

网友评论

      本文标题:shell爬虫批量下载mp3

      本文链接:https://www.haomeiwen.com/subject/ujnxfftx.html