shell爬蟲批量下載mp3

最近喜歡聽王玥波的《雍正劍俠圖》,搜到某網(wǎng)站上有全套,可惜,只能一回一回地手動(dòng)下載,現(xiàn)在出到了第六部,每一部都有上百回,手動(dòng)點(diǎn)鼠標(biāo)下載得下到猴年馬月去了。古人說(shuō):“Where there is a shell, there is a way”,用shell腳本來(lái)做這件事吧。

Where there is a shell, there is a way.

shell腳本由linux命令組合而成,由于linux現(xiàn)有的大量命令工具都經(jīng)過了長(zhǎng)期的優(yōu)化和標(biāo)準(zhǔn)化,其執(zhí)行效率和移植性都很高。

shell爬蟲的核心是curl,curl可以下載網(wǎng)頁(yè),解析http response頭信息,也可以指定http request頭信息,且可處理cookie,具備web瀏覽器的基本功能,支持HTTPS、FTP、FTPS、TELNET、LDAP等協(xié)議。

強(qiáng)大的curl

首先,是解析每一回音頻的url,每一回對(duì)應(yīng)一個(gè)鏈接頁(yè)面,地址的編排很簡(jiǎn)單,如第一回就是:

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

想當(dāng)然地使用chrome查看音頻的加載過程,結(jié)果發(fā)現(xiàn)音頻文件的url直接寫在了源碼里:

<a  id='down'><img src="http://xxx.com/e/data/images/download.jpg" alt="下載雍正劍俠圖第五部 001回"></a>

而且該網(wǎng)頁(yè)中只有這一行出現(xiàn)了.mp3,不過文件名是隨機(jī)生成的。

每一回的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

下面來(lái)逐行分析一下for循環(huán)究竟做了什么。

$page_i是第i回的下載頁(yè)面,不過并不是下載鏈接,下載鏈接$mp3_i_url需要解析出來(lái)。

curl ${page_i}

獲取該頁(yè)面的html代碼,該頁(yè)面編碼是GB2312,標(biāo)準(zhǔn)輸出的漢字是亂碼,如不進(jìn)行處理可能會(huì)導(dǎo)致腳本執(zhí)行中報(bào)錯(cuò)退出,因此使用iconv進(jìn)行轉(zhuǎn)碼:

iconv -c -f gb2312 -t utf-8

將網(wǎng)頁(yè)編碼從gb2312轉(zhuǎn)為utf-8,選項(xiàng)-c表示忽略轉(zhuǎn)碼過程中的報(bào)錯(cuò),以避免腳本意外中止。

grep '\.mp3'

使用grep查找含有'.mp3'的行,這里使用了轉(zhuǎn)義符'\'。

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

這是截取mp3文件的下載鏈接,awk是一個(gè)強(qiáng)大的工具,可以將一行文本分解為多列進(jìn)行處理,這里指定"為分割符,將這行原代碼:

<a  id='down'><img src="http://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回的下載任務(wù)。

以上代碼已經(jīng)達(dá)到了我們的目的,不過考慮到網(wǎng)站可能采取的反爬措施,再加幾行:

#!/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

主要做了兩種反反爬措施,一是下完一回后延時(shí)30s,這個(gè)比較好理解。

二是使用curl-A選項(xiàng),在request中指定User-Agent字段,用于模擬客戶端設(shè)備和瀏覽器:

curl -A ${user_agent} ${page_i}

不過后來(lái)發(fā)現(xiàn),該網(wǎng)站的反爬措施好像并不完善。

到此為止,腳本已經(jīng)完成,丟到Raspberry pi上去跑了一晚,第二天早上,成功收獲了熱熱乎乎的《雍正劍俠圖》。

運(yùn)行效果

對(duì)于簡(jiǎn)單的爬蟲功能,和python相比,shell的代碼量顯然更少,寫起來(lái)也更快,畢竟這東西基本上只是一次性的,殺雞還是不要?jiǎng)优5读恕?/p>

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容