摘要:如圖點擊音頻發出請求,請求返回數據里面包含真實音頻鏈接,如圖寫爬蟲需求分析完了,那現在當然是寫爬蟲了,首先爬取主播頁,拿到,然后根據發送請求拿到真實音頻地址。
最近一直在學英語,因此寫了個爬蟲爬取歌單并下載,然后隨時都可以聽。 GitHub地址:https://github.com/leeseean/nodejs-crawler。頁面分析
要用爬蟲下載音頻,那自然是要找到音頻鏈接了。而網站的音頻鏈接沒有直接暴露出來,因此需要分析找出獲取音頻鏈接的辦法。 進入喜馬拉雅官網主頁,隨便找一個主播的頁面進入,我這里找的是[英語主播Emily](http://www.ximalaya.com/29101549/album/2801092)的主頁,然后里面有她的播單,F12打開一看這些歌單都沒有直接寫音頻鏈接。但是還是有一些規律的,每個音頻都有一個ID,后面點擊這個音頻的時候,會有一個AJAX請求,請求的鏈接就包含這個ID,這個請求會返回音頻的真實鏈接,這樣就拿到了音頻鏈接。如圖
點擊音頻發出AJAX請求,請求返回數據里面包含真實音頻鏈接,如圖寫爬蟲
需求分析完了,那現在當然是寫爬蟲了,首先爬取主播頁,拿到ID,然后根據ID發送AJAX請求拿到真實音頻地址。 用的模塊有cheerio和request。
const request = require("request"); const fs = require("fs"); const cheerio = require("cheerio"); //這個時間后面設置cookie需要用到 const formatTime = (new Date()).toLocaleString().replace(///g, "-").replace(/[u4E00-u9FA5]/g, "");
直接用request(url,callcack)發現返回一個301重定向的頁面,因此要設置uset-agent和cookie才能正確訪問到頁面。如圖,
相應設置代碼如下:
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" } }; }
請求到頁面到拿到所有音頻的ID,并根據音頻ID發送AJAX請求,代碼如下:
function getListIdsCallback(error, response, body) { if (!error && response.statusCode === 200) { const listIds = [];//存放所有音頻ID的數組 const $ = cheerio.load(body); $("div.album_soundlist > ul > li > div > a.title").each((index, item) => { listIds.push($(item).attr("href").split("/")[3]); }); getAudioJson(listIds);//獲取音頻真實鏈接并下載音頻 } }獲取音頻真實鏈接并下載音頻
代碼如下:
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一開始是使用一個循環去下載,后面發現一下子同時開啟幾十個下載node根本吃不消,下下來的音頻不完整,后面采用一個一個下載的辦法,就完全解決的這個問題。相關代碼如下:
const id = listIds.shift();//每次取出一個id去請求 downloadFile(JsonData["play_path"], `${JsonData["id"]}.m4a`, (e) => { console.log(`下載完畢${JsonData["id"]}`); getAudioJson(listIds);//下載完后再次啟動請求 });總結
先寫到這了。爬蟲的關鍵就是找出真實地址,然后抓頁面的時候如果抓不到記得補充cookie,設置user-agent等一類參數。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/89717.html
摘要:前提本項目地址如果需要,可以到本地打開可直接查看爬蟲數據目標爬取斗魚正在直播的主播數據房間號,在線人數,房間標題,主播名稱,直播分類等等依賴構建安裝包的應用程序框架小型漸進式客戶端請求庫,和模塊具有相同的,具有許多高級客戶端功能可以 前提 本項目github地址:https://github.com/janyin/dou...如果需要,可以clone到本地 $ npm install ...
摘要:引言馬上情人節就要來了,是否需要一首歌來撫慰你,受傷或躁動的心靈。來吧,今天教你用行代碼搞定熱門歌單。爬取的效果如下總結本文旨在安撫你因情人節受傷的小心靈,同時帶你入個爬蟲的門,感受下的強大。 0. 引言 馬上314情人節就要來了,是否需要一首歌來撫慰你,受傷或躁動的心靈。來吧,今天教你用15行代碼搞定熱門歌單。學起來并聽起來吧。 本文使用的是Selenium模塊,它是一個自動化測試工...
閱讀 1213·2021-09-03 10:44
閱讀 614·2019-08-30 13:13
閱讀 2804·2019-08-30 13:11
閱讀 1974·2019-08-30 12:59
閱讀 1042·2019-08-29 15:32
閱讀 1603·2019-08-29 15:25
閱讀 999·2019-08-29 12:24
閱讀 1288·2019-08-27 10:58