用Python爬取網易雲音樂熱評
本文旨在記錄Python爬蟲實例:網易雲熱評下載
由於是從零開始,本文內容借鑒於各種網絡資源,如有侵權請告知作者。
要看懂本文,需要具備一點點網絡相關知識。不過沒有關系,不懂的概念自行百度,基本都能解決。
1. 基本知識
1.1 爬蟲是什么
如果我們把互聯網比作一張大的蜘蛛網,數據便是存放於蜘蛛網的各個節點,而爬蟲就是一只小蜘蛛,
沿着網絡抓取自己的獵物(數據)爬蟲指的是:向網站發起請求,獲取資源后分析並提取有用數據的程序;
從技術層面來說就是 通過程序模擬瀏覽器請求站點的行為,把站點返回的HTML代碼/JSON數據/二進制數據(圖片、視頻) 爬到本地,進而提取自己需要的數據,存放起來使用
簡言之,就是向目標網站發起請求獲得響應並提取相應數據的自動化程序。
1.2 爬蟲的基本流程
1:向服務器發起請求
通過HTTP庫向目標站點發起請求,即發送一個Request,請求可以包含額外的headers等信息,等待服務器的響應。
2:獲取響應內容
如果服務器正常響應,會得到一個Response,Response的內容便是所要獲取的頁面內容,類型可能有HTML、JSON、二進制文件(如圖片、視頻等類型)。
3:解析內容
得到的內容可能是HTML,可以用正則表達式、網頁解析庫進行解析。可能是JSON,可以直接轉成JOSN對象進行解析,可能是二進制數據,可以保存或者進一步處理
4:保存內容
保存形式多樣,可以保存成文本,也可以保存至數據庫,或者保存成特定格式的文件。————————————————
原文鏈接:https://blog.csdn.net/qq_29186489/java/article/details/78587634
1.3 Request與Response
Request中包含哪些內容?
1:請求方式
主要是GET、POST兩種類型,另外還有HEAD、PUT、DELETE、OPTIONS等。
2:請求URL
URL全稱是統一資源定位符,如一個網頁文檔、一張圖片、一個視頻等都可以用URL來唯一來確定
3:請求頭
包含請求時的頭部信息,如User-Agent、Host、Cookies等信息
4:請求體
請求時額外攜帶的數據,如表單提交時的表單數據Response中包含哪些內容?
1:響應狀態
有多種響應狀態,如200代表成功,301代表跳轉,404代表找不到頁面,502代表服務器錯誤等
2:響應頭
如內容類型、內容長度、服務器信息、設置cookies等等
3:響應體
最主要的部分,包含了請求資源的內容,如網頁HTML、圖片二進制數據等。
示例代碼:from fake_useragent import UserAgent import requests ua=UserAgent() #請求的網址 url="http://www.baidu.com" #請求頭 headers={"User-Agent":ua.random} #請求網址 response=requests.get(url=url,headers=headers) #響應體內容 print(response.text) #響應狀態信息 print(response.status_code) #響應頭信息 print(response.headers)
能抓到怎樣的數據?
1:網頁文本
如HTML文檔、JSON格式文本等
2:圖片文件
獲取的是二進制文件,保存為圖片格式
3:視頻
同為二進制文件,保存為視頻格式即可
4:其他
只要能夠請求到的,都能夠獲取到
————————————————
原文鏈接:https://blog.csdn.net/qq_29186489/java/article/details/78587634
2.准備工作
2.1 網頁數據請求及響應
這里,已有眾多網友給出了請求方式的具體請求方式。
new-june博客中詳細給出了請求查看方式以及提交表單中兩個加密參數的破解。
實際上 Rotation給出了整個爬取過程,本文也是在其代碼基礎上完成的。
簡單來說,就是通過使用瀏覽器的開發者工具,找到數據請求方式以及目標數據的來源,從而進行程序化請求與數據處理。
2.2 本文思路
首先,發送請求(request),獲取歌單中每一首歌名及其ID(正則表達式:re);其次,獲取每首歌的熱評內容(json),評論用戶昵稱,點贊數;將獲得的數據寫入Excel文件中(openpyxl)。
2.3 Python環境准備
王樹義以Anacoda為例,詳細的給出了其安裝過程。Anacoda中已經集成了眾多開發環境,本文在其中的Spyder環境中進行程序開發。
根據思路,本文需要以下模塊:
request
re
json
openpyxl
3. 程序解讀
3.1 加載相關模塊
import re
import requests
import json
import openpyxl
3.2 生成表格文件
wb=openpyxl.Workbook()
sheet=wb.active
sheet為excel中第一個sheet名
3.3 歌名及ID獲取函數
def get_all_hotsongs():
"""抓取歌單中所有歌曲"""
url = 'https://music.163.com/playlist?id=2340969541' #此鏈接可替換為任意歌單鏈接,需要注意的是,直接從瀏覽器復制后需要去掉url中的/#
#構造模擬請求信息
headers = {
'Cookie':'__e_=1515461191756; _ntes_nnid=af802a7dd2cafc9fef605185da6e73fb,1515461190617; _ntes_nuid=af802a7dd2cafc9fef605185da6e73fb; JSESSIONID-WYYY=HMyeRdf98eDm%2Bi%5CRnK9iB%5ChcSODhA%2Bh4jx5t3z20hhwTRsOCWhBS5Cpn%2B5j%5CVfMIu0i4bQY9sky%5CsvMmHhuwud2cDNbFRD%2FHhWHE61VhovnFrKWXfDAp%5CqO%2B6cEc%2B%2BIXGz83mwrGS78Goo%2BWgsyJb37Oaqr0IehSp288xn5DhgC3Cobe%3A1515585307035; _iuqxldmzr_=32; __utma=94650624.61181594.1515583507.1515583507.1515583507.1; __utmc=94650624; __utmz=94650624.1515583507.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); __utmb=94650624.4.10.1515583507',
'Host':'music.163.com',
'Refere':'http://music.163.com/',
'Upgrade-Insecure-Requests':'1',
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'
}
r = requests.get(url,headers=headers)
#使用正則表達式匹配正文響應,獲取歌名及歌曲ID
reg1 = r'<ul class="f-hide"><li><a href="/song\?id=\d*?">.*</a></li></ul>'
result_contain_songs_ul = re.compile(reg1).findall(r.text)
result_contain_songs_ul = result_contain_songs_ul[0]
reg2 = r'<li><a href="/song\?id=\d*?">(.*?)</a></li>'
reg3 = r'<li><a href="/song\?id=(\d*?)">.*?</a></li>'
hot_songs_name = re.compile(reg2).findall(result_contain_songs_ul)
hot_songs_id = re.compile(reg3).findall(result_contain_songs_ul)
#返回歌曲名 歌曲id
return hot_songs_name,hot_songs_id
3.4 獲取熱評函數
def get_hotcommnets(hot_songs_name,hot_songs_id):
"""抓取歌曲熱評"""
#評論請求url
url = 'http://music.163.com/weapi/v1/resource/comments/R_SO_4_'+hot_songs_id+'?csrf_token='
#請求頭構造
headers = {
'Host':'music.163.com',
'Proxy-Connection':'keep-alive',
'Origin':'http://music.163.com',
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)',
'Content-Type':'application/x-www-form-urlencoded',
'Accept':'*/*',
'Referer':'http://music.163.com/song?id='+hot_songs_id+'',
'Accept-Encoding':'gzip, deflate',
'Accept-Language':'zh,zh-TW;q=0.9,en-US;q=0.8,en;q=0.7',
'Cookie':'__e_=1515461191756; _ntes_nnid=af802a7dd2cafc9fef605185da6e73fb,1515461190617; _ntes_nuid=af802a7dd2cafc9fef605185da6e73fb; _iuqxldmzr_=32; __utmc=94650624; __utmz=94650624.1515628584.2.2.utmcsr=baidu|utmccn=(organic)|utmcmd=organic; JSESSIONID-WYYY=TO%2BtUvrTWONNwB%2BgzDpfjFDiggKiS%2FfpMYNam%2BWGooHNka%2BwMhdsT%5CY%2Fn%2FpSMJwo4skFIK1T%2FNjd95lbGHWMQr5d5qcMRPB9SVKWK8UuBs1OGugZ4lFwipwjwWbCepSw%5CjWv31i1Qt%5CWWwtrFzzktj8CdCzniAw%5CgFCElUJnsQygY0MA%3A1515635604215; __utma=94650624.61181594.1515583507.1515630648.1515633862.4; __utmb=94650624.2.10.1515633862'
}
#評論第一頁請求表單提交參數
data = {
'params':'cG5yxYo1s0E9Eqv4QWJLM0fdPiJr0+GfKwqcGPulhOtGJ16gEBopaMhe6XeVNKDigMlpCaV7vrDNQLIOPIaTpAjlcJv+hjdCek6nL0ODfHt9ZEmtkTmU4r/+SA6Vno+o+c4EaPvhghNUXRMdVM/LltKvVanwOSvVhcqUPw9qij1d1akcxweLOWf1hKh2/q/m',
'encSecKey':'a6c21ac04a44dca0e68174f9dfa85537a2694ecf7b43bdcd46a90836209a3d68008b430b54751bc0f56b12b6da38a265afcef1edbf687d70d1eb853144e920fea28e19a8c6145b7bad33e40d077e8a689b4bf67b367db815278af4ef227b02d85e609007106b7fc4a547bf96a1b90b0eda85bca6cc79ca6fc6559d00060d4184'
}
#獲取響應
response = requests.post(url,data=data,headers=headers)
#格式化響應正文hotComments熱評節點
hotcomments = json.loads(response.text)['hotComments']
#遍歷熱評內容 保存到當前excel
for i in range(len(hotcomments)):
user_name = hotcomments[i]['user']['nickname'] #獲取用戶昵稱
comment = hotcomments[i]['content'] #獲取熱評內容
like_num = hotcomments[i]['likedCount'] #獲取點贊數
x=[hot_songs_name,hot_songs_id,user_name,comment,like_num]
#將上述信息連續按行寫入excel
sheet.append(x)
3.5 函數調用
#調用方法 獲得歌曲名 歌曲id
hot_songs_name,hot_songs_id = get_all_hotsongs()
#循環遍歷抓取所有熱評
num = 0
while num < len(hot_songs_name):
print('正在抓取網易雲音樂第%d首歌曲熱評...'%(num+1))
get_hotcommnets(hot_songs_name[num],hot_songs_id[num])
print('第%d首歌曲熱評抓取成功'%(num+1))
num+=1
wb.save(filename = 'Formular.xlsx')
4.結果驗證
5. 附
代碼實測可用,博客園中markdown縮進不友好,換行可能會導致代碼出錯,請注意。