摘要:如圖點(diǎn)擊音頻發(fā)出請(qǐng)求,請(qǐng)求返回?cái)?shù)據(jù)里面包含真實(shí)音頻鏈接,如圖寫(xiě)爬蟲(chóng)需求分析完了,那現(xiàn)在當(dāng)然是寫(xiě)爬蟲(chóng)了,首先爬取主播頁(yè),拿到,然后根據(jù)發(fā)送請(qǐng)求拿到真實(shí)音頻地址。
最近一直在學(xué)英語(yǔ),因此寫(xiě)了個(gè)爬蟲(chóng)爬取歌單并下載,然后隨時(shí)都可以聽(tīng)。 GitHub地址:https://github.com/leeseean/nodejs-crawler。頁(yè)面分析
要用爬蟲(chóng)下載音頻,那自然是要找到音頻鏈接了。而網(wǎng)站的音頻鏈接沒(méi)有直接暴露出來(lái),因此需要分析找出獲取音頻鏈接的辦法。 進(jìn)入喜馬拉雅官網(wǎng)主頁(yè),隨便找一個(gè)主播的頁(yè)面進(jìn)入,我這里找的是[英語(yǔ)主播Emily](http://www.ximalaya.com/29101549/album/2801092)的主頁(yè),然后里面有她的播單,F(xiàn)12打開(kāi)一看這些歌單都沒(méi)有直接寫(xiě)音頻鏈接。但是還是有一些規(guī)律的,每個(gè)音頻都有一個(gè)ID,后面點(diǎn)擊這個(gè)音頻的時(shí)候,會(huì)有一個(gè)AJAX請(qǐng)求,請(qǐng)求的鏈接就包含這個(gè)ID,這個(gè)請(qǐng)求會(huì)返回音頻的真實(shí)鏈接,這樣就拿到了音頻鏈接。如圖
點(diǎn)擊音頻發(fā)出AJAX請(qǐng)求,請(qǐng)求返回?cái)?shù)據(jù)里面包含真實(shí)音頻鏈接,如圖寫(xiě)爬蟲(chóng)
需求分析完了,那現(xiàn)在當(dāng)然是寫(xiě)爬蟲(chóng)了,首先爬取主播頁(yè),拿到ID,然后根據(jù)ID發(fā)送AJAX請(qǐng)求拿到真實(shí)音頻地址。 用的模塊有cheerio和request。
const request = require("request"); const fs = require("fs"); const cheerio = require("cheerio"); //這個(gè)時(shí)間后面設(shè)置cookie需要用到 const formatTime = (new Date()).toLocaleString().replace(///g, "-").replace(/[u4E00-u9FA5]/g, "");
直接用request(url,callcack)發(fā)現(xiàn)返回一個(gè)301重定向的頁(yè)面,因此要設(shè)置uset-agent和cookie才能正確訪問(wèn)到頁(yè)面。如圖,
相應(yīng)設(shè)置代碼如下:
function setOptions({ url, cookies, contentType }) { const jar = request.jar(); jar.setCookie(request.cookie(cookies), url); return { url: url, jar: jar, method: "GET", headers: { "Connection": "keep-alive", "Content-Type": contentType, "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36" } }; }
請(qǐng)求到頁(yè)面到拿到所有音頻的ID,并根據(jù)音頻ID發(fā)送AJAX請(qǐng)求,代碼如下:
function getListIdsCallback(error, response, body) { if (!error && response.statusCode === 200) { const listIds = [];//存放所有音頻ID的數(shù)組 const $ = cheerio.load(body); $("div.album_soundlist > ul > li > div > a.title").each((index, item) => { listIds.push($(item).attr("href").split("/")[3]); }); getAudioJson(listIds);//獲取音頻真實(shí)鏈接并下載音頻 } }獲取音頻真實(shí)鏈接并下載音頻
代碼如下:
function getAudioJson(listIds) { if (listIds.length === 0) { return; } const id = listIds.shift(); request(setOptions({ url: `http://www.ximalaya.com/tracks/${id}.json`, cookies: `_xmLog=xm_1510364052559_j9unrdjjmwt7gx; login_from=qq; nickname=All2005; login_type=QQ; 1&remember_me=y; 1&_token=96575028&ecb632710362104767080ce01362b33cc881; trackType=web; x_xmly_traffic=utm_source%3A%26utm_medium%3A%26utm_campaign%3A%26utm_content%3A%26utm_term%3A%26utm_from%3A; Hm_lvt_4a7d8ec50cfd6af753c4f8aee3425070=1510364053; Hm_lpvt_4a7d8ec50cfd6af753c4f8aee3425070=1510376453; _ga=GA1.2.1519968795.1510364053; _gat=1; 1_l_flag=96575028&ecb632710362104767080ce01362b33cc881_${formatTime}; msgwarn=%7B%22category%22%3A%22%22%2C%22newMessage%22%3A0%2C%22newNotice%22%3A0%2C%22newComment%22%3A0%2C%22newQuan%22%3A0%2C%22newFollower%22%3A0%2C%22newLikes%22%3A0%7D`, contentType: "text/html;charset=utf-8", }), (error, response, body) => { return getAudioJsonCallback(error, response, body, listIds); }); } function getAudioJsonCallback(error, response, body, listIds) { if (!error && response.statusCode === 200) { const JsonData = JSON.parse(body); downloadFile(JsonData["play_path"], `${JsonData["id"]}.m4a`, (e) => { console.log(`下載完畢${JsonData["id"]}`); getAudioJson(listIds); }); } } function downloadFile(url, filename, callback) { const stream = fs.createWriteStream(filename); request(url).pipe(stream).on("close", callback); }代碼技巧
這里獲取到listIds一開(kāi)始是使用一個(gè)循環(huán)去下載,后面發(fā)現(xiàn)一下子同時(shí)開(kāi)啟幾十個(gè)下載node根本吃不消,下下來(lái)的音頻不完整,后面采用一個(gè)一個(gè)下載的辦法,就完全解決的這個(gè)問(wèn)題。相關(guān)代碼如下:
const id = listIds.shift();//每次取出一個(gè)id去請(qǐng)求 downloadFile(JsonData["play_path"], `${JsonData["id"]}.m4a`, (e) => { console.log(`下載完畢${JsonData["id"]}`); getAudioJson(listIds);//下載完后再次啟動(dòng)請(qǐng)求 });總結(jié)
先寫(xiě)到這了。爬蟲(chóng)的關(guān)鍵就是找出真實(shí)地址,然后抓頁(yè)面的時(shí)候如果抓不到記得補(bǔ)充cookie,設(shè)置user-agent等一類參數(shù)。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/89717.html
摘要:前提本項(xiàng)目地址如果需要,可以到本地打開(kāi)可直接查看爬蟲(chóng)數(shù)據(jù)目標(biāo)爬取斗魚(yú)正在直播的主播數(shù)據(jù)房間號(hào),在線人數(shù),房間標(biāo)題,主播名稱,直播分類等等依賴構(gòu)建安裝包的應(yīng)用程序框架小型漸進(jìn)式客戶端請(qǐng)求庫(kù),和模塊具有相同的,具有許多高級(jí)客戶端功能可以 前提 本項(xiàng)目github地址:https://github.com/janyin/dou...如果需要,可以clone到本地 $ npm install ...
摘要:引言馬上情人節(jié)就要來(lái)了,是否需要一首歌來(lái)?yè)嵛磕悖軅蛟陝?dòng)的心靈。來(lái)吧,今天教你用行代碼搞定熱門(mén)歌單。爬取的效果如下總結(jié)本文旨在安撫你因情人節(jié)受傷的小心靈,同時(shí)帶你入個(gè)爬蟲(chóng)的門(mén),感受下的強(qiáng)大。 0. 引言 馬上314情人節(jié)就要來(lái)了,是否需要一首歌來(lái)?yè)嵛磕悖軅蛟陝?dòng)的心靈。來(lái)吧,今天教你用15行代碼搞定熱門(mén)歌單。學(xué)起來(lái)并聽(tīng)起來(lái)吧。 本文使用的是Selenium模塊,它是一個(gè)自動(dòng)化測(cè)試工...
閱讀 1207·2021-09-03 10:44
閱讀 604·2019-08-30 13:13
閱讀 2796·2019-08-30 13:11
閱讀 1967·2019-08-30 12:59
閱讀 1034·2019-08-29 15:32
閱讀 1595·2019-08-29 15:25
閱讀 987·2019-08-29 12:24
閱讀 1277·2019-08-27 10:58