溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何用Python爬取網(wǎng)易云音樂輯的圖片及專輯名和專輯出版時間

發(fā)布時間:2021-10-26 10:11:06 來源:億速云 閱讀:157 作者:柒染 欄目:云計算

這期內(nèi)容當中小編將會給大家?guī)碛嘘P如何用Python爬取網(wǎng)易云音樂輯的圖片及專輯名和專輯出版時間,文章內(nèi)容豐富且以專業(yè)的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。

一、前言

前文說過我的設計師小伙伴的設計需求,他想做一個披頭士樂隊歷年專輯的瀑布圖。

通過搜索,發(fā)現(xiàn)網(wǎng)易云音樂上有比較全的歷年專輯信息加配圖,圖片質(zhì)量還可以,雖然有大有小。

我的例子怎么都是爬取圖片?(誰讓你總是跟設計師小伙伴一起玩耍。。。)看來圖片對于設計師來說還是有著很深的情節(jié),那就看他用這些圖片能做出什么樣的作品啦,期待一下,后續(xù)會展示一下他的作品。

其實爬取網(wǎng)易云音樂跟之前爬取的網(wǎng)站稍稍有點不同,當然,爬蟲寫的多了就覺得套路都是固定的,見招拆招而已。

二、運行環(huán)境

我的運行環(huán)境如下:

  • 系統(tǒng)版本
    Windows10。

  • Python版本
    Python3.5,推薦使用Anaconda 這個科學計算版本,主要是因為它自帶一個包管理工具,可以解決有些包安裝錯誤的問題。去Anaconda官網(wǎng),選擇Python3.5版本,然后下載安裝。

  • IDE
    我使用的是PyCharm,是專門為Python開發(fā)的IDE。

三、實戰(zhàn)

上面提到過,網(wǎng)易云音樂的網(wǎng)頁跟普通的網(wǎng)頁相比主要有兩點不同:

  • 網(wǎng)頁是 js 動態(tài)加載的

  • 使用了iframe框架
    所以,首先,網(wǎng)頁請求不能使用requests庫,需要使用Selenium + PhatomJS。其次,使用Selenium + PhatomJS后,還需要針對 iframe 做特定處理。

廢話不多說,看實際操作步驟:
首先打開網(wǎng)頁 http://music.163.com

如何用Python爬取網(wǎng)易云音樂輯的圖片及專輯名和專輯出版時間

然后看到如下頁面,選擇紅框中的“所有專輯”,點擊。

如何用Python爬取網(wǎng)易云音樂輯的圖片及專輯名和專輯出版時間

我們需要的就是所有專輯的圖片、專輯名和專輯出版時間??吹竭@就可以構想一下爬蟲的爬取邏輯了。定位到該頁面,然后獲取頁碼,然后挨個請求頁面來爬取頁面中的內(nèi)容。
點擊一下翻頁按鈕看看url 有沒有什么規(guī)律。

點擊第二頁后,看到上面的地址欄!?。】吹竭@個地址欄我都懶得翻頁了。。。

limit 參數(shù)是限制一個頁面加載專輯的個數(shù)
offset 參數(shù)是前面過濾多少個專輯,現(xiàn)在是一頁12個專輯,所以第二頁是offset=12,第三頁offset=24,以此類推。。。

一共9頁,一頁12個,也不到120個。So… … 改一下url 就不用翻頁了?。?/p>

limit 參數(shù)等于120,offset 參數(shù) 等于0,就搞定了!輸入下面的url,看看是不是所有的專輯都加載出來了。

http://music.163.com/#/artist/album?id=101988&limit=120&offset=0

下面就開始爬蟲代碼了。
這里我們會用到上一篇博文中寫好的幾個工具方法:

    def save_img(self, url, file_name): ##保存圖片
        print('開始請求圖片地址,過程會有點長...')
        img = self.request(url)
        print('開始保存圖片')
        f = open(file_name, 'ab')
        f.write(img.content)
        print(file_name,'圖片保存成功!')
        f.close()

    def request(self, url):  #封裝的requests 請求
        r = requests.get(url)  # 像目標url地址發(fā)送get請求,返回一個response對象。有沒有headers參數(shù)都可以。
        return r

    def mkdir(self, path):  ##這個函數(shù)創(chuàng)建文件夾
        path = path.strip()
        isExists = os.path.exists(path)
        if not isExists:
            print('創(chuàng)建名字叫做', path, '的文件夾')
            os.makedirs(path)
            print('創(chuàng)建成功!')
            return True
        else:
            print(path, '文件夾已經(jīng)存在了,不再創(chuàng)建')
            return False

    def get_files(self, path): #獲取文件夾中的文件名稱列表
        pic_names = os.listdir(path)
        return pic_names

OK, 開始我們的爬蟲邏輯部分:

這里值得注意的是,該頁面使用frame 框架,使用Selenium + PhantomJS 后并不會加載iframe 框架中的網(wǎng)頁內(nèi)容。iframe 框架相當于在頁面中又加載了一個頁面,需要使用Selenium 的 switch_to.frame() 方法加載(官網(wǎng)給的方法是switch_to_frame(),但是IDE提醒使用前面的方法替代該方法)。

看下面的網(wǎng)頁結構,iframe的id是“g_iframe”:

如何用Python爬取網(wǎng)易云音樂輯的圖片及專輯名和專輯出版時間

加載 iframe 框架中的內(nèi)容:

driver = webdriver.PhantomJS()
driver.get(self.init_url)
driver.switch_to.frame("g_iframe")
html = driver.page_source

然后找到所有的封面元素:

根據(jù)上圖的網(wǎng)頁結構可以看出,所有的專輯信息都在ul 標簽里面,每一個專輯在一個li 標簽里。li 標簽中包含了圖片url、專輯名字、以及專輯時間。

抓取其中的內(nèi)容就好了。

all_li = BeautifulSoup(html, 'lxml').find(id='m-song-module').find_all('li')

for li in all_li:
    album_img = li.find('img')['src']
    album_name = li.find('p', class_='dec')['title']
    album_date = li.find('span', class_='s-fc3').get_text()

這里獲取到的圖片url 依然是有圖片寬高參數(shù)的,所以要過濾寬高參數(shù):
http://p4.music.126.net/pLA1GX0KtU-vU4ZA6Cr-OQ==/1401877340532770.jpg?param=120y120

把問號后面的參數(shù)過濾掉:

end_pos = album_img.index('?')  #找到問號的位置
album_img_url = album_img[:end_pos]  #截取問號之前的內(nèi)容

圖片命名邏輯:專輯時間 + 專輯名。
專輯名可能有一些特殊字符,需要替換掉!
photo_name = album_date + ' - ' + album_name.replace('/','').replace(':',',') + '.jpg'

再使用上一篇博文例子中的去重邏輯,修改后的爬蟲邏輯部分如下:

    def spider(self):
        print("Start!")
        driver = webdriver.PhantomJS()
        driver.get(self.init_url)
        driver.switch_to.frame("g_iframe")
        html = driver.page_source

        self.mkdir(self.folder_path)  # 創(chuàng)建文件夾
        print('開始切換文件夾')
        os.chdir(self.folder_path)  # 切換路徑至上面創(chuàng)建的文件夾

        file_names = self.get_files(self.folder_path)  # 獲取文件夾中的所有文件名,類型是list

        all_li = BeautifulSoup(html, 'lxml').find(id='m-song-module').find_all('li')
        # print(type(all_li))

        for li in all_li:
            album_img = li.find('img')['src']
            album_name = li.find('p', class_='dec')['title']
            album_date = li.find('span', class_='s-fc3').get_text()
            end_pos = album_img.index('?')
            album_img_url = album_img[:end_pos]

            photo_name = album_date + ' - ' + album_name.replace('/','').replace(':',',') + '.jpg'
            print(album_img_url, photo_name)

            if photo_name in file_names:
                print('圖片已經(jīng)存在,不再重新下載')
            else:
                self.save_img(album_img_url, photo_name)

其實相對于上篇博文的例子,這個爬蟲的邏輯部分還是挺簡潔的。

最后上一個完整的代碼:也可以從GitHub下載

from selenium import webdriver
from bs4 import BeautifulSoup
import requests
import os

class AlbumCover():

    def __init__(self):
        self.init_url = "http://music.163.com/#/artist/album?id=101988&limit=120&offset=0" #請求網(wǎng)址
        self.folder_path = "C:\D\TheBeatles" #想要存放的文件目錄

    def save_img(self, url, file_name):  ##保存圖片
        print('開始請求圖片地址,過程會有點長...')
        img = self.request(url)
        print('開始保存圖片')
        f = open(file_name, 'ab')
        f.write(img.content)
        print(file_name, '圖片保存成功!')
        f.close()

    def request(self, url):  # 封裝的requests 請求
        r = requests.get(url)  # 像目標url地址發(fā)送get請求,返回一個response對象。有沒有headers參數(shù)都可以。
        return r

    def mkdir(self, path):  ##這個函數(shù)創(chuàng)建文件夾
        path = path.strip()
        isExists = os.path.exists(path)
        if not isExists:
            print('創(chuàng)建名字叫做', path, '的文件夾')
            os.makedirs(path)
            print('創(chuàng)建成功!')
            return True
        else:
            print(path, '文件夾已經(jīng)存在了,不再創(chuàng)建')
            return False

    def get_files(self, path):  # 獲取文件夾中的文件名稱列表
        pic_names = os.listdir(path)
        return pic_names

    def spider(self):
        print("Start!")
        driver = webdriver.PhantomJS()
        driver.get(self.init_url)
        driver.switch_to.frame("g_iframe")
        html = driver.page_source

        self.mkdir(self.folder_path)  # 創(chuàng)建文件夾
        print('開始切換文件夾')
        os.chdir(self.folder_path)  # 切換路徑至上面創(chuàng)建的文件夾

        file_names = self.get_files(self.folder_path)  # 獲取文件夾中的所有文件名,類型是list

        all_li = BeautifulSoup(html, 'lxml').find(id='m-song-module').find_all('li')
        # print(type(all_li))

        for li in all_li:
            album_img = li.find('img')['src']
            album_name = li.find('p', class_='dec')['title']
            album_date = li.find('span', class_='s-fc3').get_text()
            end_pos = album_img.index('?')
            album_img_url = album_img[:end_pos]

            photo_name = album_date + ' - ' + album_name.replace('/', '').replace(':', ',') + '.jpg'
            print(album_img_url, photo_name)

            if photo_name in file_names:
                print('圖片已經(jīng)存在,不再重新下載')
            else:
                self.save_img(album_img_url, photo_name)

album_cover = AlbumCover()
album_cover.spider()

執(zhí)行結果:
看看文件夾里面什么樣:
歷年的專輯封面已經(jīng)到手啦,還有專輯的名稱和發(fā)行日期。

四、后語

這個實戰(zhàn)很好的運用了咱們之前講解的知識:

  • 使用Selenium + PhatomJS 抓取動態(tài)頁面

  • 使用Selenium 的switch_to.frame() 加載 iframe 中的內(nèi)容

  • 使用requests 庫獲取圖片

  • 使用BeautifulSoup 庫解析抓取網(wǎng)頁內(nèi)容。

  • 使用os 庫創(chuàng)建文件夾和獲取文件夾中的文件名稱列表

上述就是小編為大家分享的如何用Python爬取網(wǎng)易云音樂輯的圖片及專輯名和專輯出版時間了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關知識,歡迎關注億速云行業(yè)資訊頻道。

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。

AI