網易雲音樂火不火我不知道,但是評論很火,也見過很多的文章抓取網易雲音樂,今天自己抓一次,感覺有一點小坑,尤其是對初學者來說,今天正好把我抓取的過程和遇到的問題說一下。
找歌曲
網易雲音樂的網址是https://music.163.com/,打來連接配接我們選擇如下資訊
之是以找熱門歌曲是評論多。這樣抓到的資料也多。如果你是Chrome浏覽器,F12打開調試工具,找到如下資訊,用這個來通路歌曲清單,其他的浏覽器自己查去吧,像什麼firebug什麼的,自己下載下傳。
然後找到清單需要通路的url
用這個連結去通路,但是要注意的是,他的頁面是嵌套了iframe的,是以如果用單存的xpath是找不到資訊的,是以需要使用selenium,他也沒什麼,selenium這也沒什麼,就是模仿浏覽器來爬蟲,稍微慢一點,但是基本能滿足所有的需求,這裡要做的就是根據iframe來擷取裡邊的html資訊。解析這篇我們同樣使用bs,下一篇再使用xpath來通路。
安裝selenium
pip install selenium
安裝 webdriver
下載下傳:http://npm.taobao.org/mirrors/chromedriver/2.43/,直接下載下傳你需要的版本,然後解壓到你常用的目錄。下邊會用的到
擷取soup
from bs4 import BeautifulSoup
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
song_url = "https://music.163.com/discover/toplist?id=3778678"
# 擷取驅動
driver_path = "/Users/menghaibin/Downloads/chromedriver"
chrome_options = Options()
chrome_options.add_argument('--headless')
drive = webdriver.Chrome(driver_path, chrome_options=chrome_options)
#頭資訊
headers = {
"Host": "music.163.com",
"Referer": "https://music.163.com/",
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36"
}
# 擷取soup
def getSoup(url):
drive.get(url)
iframe = drive.find_elements_by_id('g_iframe')[0]
drive.switch_to.frame(iframe)
return BeautifulSoup(drive.page_source, "lxml")
主要就是利用selenium的驅動,擷取iframe,然後從iframe中擷取html,擷取soup。
然後就是查詢歌曲,查詢頁面了,這些和上一篇的東西類似,擷取歌曲資訊沒什麼大問題,但是我看了其他人抓取評論的時候,用的是這個:
這是一個post請求,看到這個參數,加密,好,上網查了一下,有大神居然解密了,牛逼,看了看大神解析的過程,牛逼,看不懂,是以我就幹脆還是用老辦法,直接用selenium的webdriver來生成chrome的驅動來擷取資訊吧。反正結果一樣。
直接上代碼
完整版
from bs4 import BeautifulSoup
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
song_url = "https://music.163.com/discover/toplist?id=3778678"
# comment_url = "http://music.163.com/api/v1/resource/comments/R_SO_4_516997458?limit=20&offset=40"
driver_path = "/Users/menghaibin/Downloads/chromedriver"
chrome_options = Options()
chrome_options.add_argument('--headless')
drive = webdriver.Chrome(driver_path, chrome_options=chrome_options)
headers = {
"Host": "music.163.com",
"Referer": "https://music.163.com/",
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36"
}
def getSoup(url):
drive.get(url)
iframe = drive.find_elements_by_id('g_iframe')[0]
drive.switch_to.frame(iframe)
return BeautifulSoup(drive.page_source, "lxml")
# 擷取歌曲資訊
def getAllSong():
soup = getSoup(song_url)
nodes = soup.select(".m-table-rank tbody tr")
players = []
for node in nodes:
rank = node.select_one(".num").get_text()
song_href = "https://music.163.com" + node.select("td")[1].select_one("a")["href"]
song_name = node.select("td")[1].select_one("b")["title"]
song_id = node.select_one(".ply")["data-res-id"]
song_time = node.select("td")[2].select_one(".u-dur").get_text()
song_player = node.select("td")[3].select_one("span")["title"]
song_info = {
"rank": rank,
"song_href": song_href,
"song_name": song_name,
"song_id": song_id,
"song_time": song_time,
"song_player": song_player
}
players.append(song_info)
return players
def getComments(song_href):
soup = getSoup(song_href)
comment_nodes = soup.select(".cmmts .itm")
comments = []
for node in comment_nodes:
comment_user = node.select_one(".s-fc7").get_text()
comment_content = node.select_one(".f-brk").get_text()
comment_content_str = str(comment_content).split(":")[1]
comment_time = node.select_one("div .time").get_text()
comment_thumb_up = node.select_one("div .rp a").get_text()
comment_thumb_up_str = str(comment_thumb_up).replace("(", "").replace(")", "").strip()
if (comment_thumb_up_str.find("萬") > 0 or (comment_thumb_up_str.strip() != '回複' and
comment_thumb_up_str.strip() != '' and int(
comment_thumb_up_str) > 1000)):
comment = {"user": comment_user,
"content": comment_content_str,
"time": comment_time,
"thumb_up": comment_thumb_up_str}
comments.append(comment)
return comments
if __name__ == '__main__':
list_songs = getAllSong()
for song in list_songs:
print(song)
print(getComments(song["song_href"]))
print("-" * 50)
drive.quit()
偷懶擷取評論
但是在晚上看到了一個混迹大神,把擷取評論的接口瞎改了一下,居然也可以擷取評論,這裡給大家貼出來
http://music.163.com/api/v1/resource/comments/R_SO_4_516997458?limit=20&offset=40
,真的是可以,也是厲害了,不過我沒有直接用這種方法,還是老一套,這個借口擷取的是json。還是挺友善的。
小結
以前都是小打小鬧,都是一些簡單的抓取,第一次遇到iframe,還是收獲挺大的,剛剛學python抓取,暫時還沒有找到替代selenium的更好的工具。