最近喜欢听王玥波的《雍正剑侠图》,搜到某网站上有全套,可惜,只能一回一回地手动下载,现在出到了第六部,每一部都有上百回,手动点鼠标下载得下到猴年马月去了。古人说:“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直接写在了源码里:

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

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

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

#!/usr/bin/env bash

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

for ((i=1; i

下面来逐行分析一下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是一个强大的工具,可以将一行文本分解为多列进行处理,这里指定"为分割符,将这行原代码:

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

分解为7列:

下载雍正剑侠图第五部

我们需要的链接是第二列,使用{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

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

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

curl -A {user_agent}{page_i}

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

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

运行效果

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

文章来源于互联网:shell爬虫批量下载mp3

发表评论