日韩久久久精品,亚洲精品久久久久久久久久久,亚洲欧美一区二区三区国产精品 ,一区二区福利

python爬蟲(chóng)學(xué)習(xí)教程,爬取網(wǎng)易云音樂(lè)!

系統(tǒng) 1916 0

運(yùn)行環(huán)境

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

系統(tǒng)版本

Windows10。

Python版本

Python3.5,推薦使用Anaconda 這個(gè)科學(xué)計(jì)算版本,主要是因?yàn)樗詭б粋€(gè)包管理工具,可以解決有些包安裝錯(cuò)誤的問(wèn)題。去Anaconda官網(wǎng),選擇Python3.5版本,然后下載安裝。

IDE

我使用的是PyCharm,是專(zhuān)門(mén)為Python開(kāi)發(fā)的IDE。這是JetBrians的產(chǎn)品

實(shí)戰(zhàn)

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

網(wǎng)頁(yè)是 js 動(dòng)態(tài)加載的

使用了iframe框架

所以,

首先,網(wǎng)頁(yè)請(qǐng)求不能使用requests庫(kù),需要使用Selenium + PhatomJS。

其次,使用Selenium + PhatomJS后,還需要針對(duì) iframe 做特定處理。

廢話不多說(shuō),看實(shí)際操作步驟:

廢話不多說(shuō),看實(shí)際操作步驟:
首先打開(kāi)網(wǎng)頁(yè) http://music.163.com

在右上角的搜索框中輸入“The Beatles”,然后會(huì)有一個(gè)下拉選項(xiàng),選擇歌手 The Beatles (紅框中的內(nèi)容)。

然后看到如下頁(yè)面,選擇紅框中的“所有專(zhuān)輯”,點(diǎn)擊。

這樣就會(huì)看見(jiàn)所有的專(zhuān)輯列表,以及下方的翻頁(yè)按鈕。

我們需要的就是所有專(zhuān)輯的圖片、專(zhuān)輯名和專(zhuān)輯出版時(shí)間。看到這就可以構(gòu)想一下爬蟲(chóng)的爬取邏輯了。定位到該頁(yè)面,然后獲取頁(yè)碼,然后挨個(gè)請(qǐng)求頁(yè)面來(lái)爬取頁(yè)面中的內(nèi)容。

點(diǎn)擊一下翻頁(yè)按鈕看看url 有沒(méi)有什么規(guī)律。

點(diǎn)擊第二頁(yè)后,看到上面的地址欄!!!看到這個(gè)地址欄我都懶得翻頁(yè)了。。。

limit 參數(shù)是限制一個(gè)頁(yè)面加載專(zhuān)輯的個(gè)數(shù)

offset 參數(shù)是前面過(guò)濾多少個(gè)專(zhuān)輯,現(xiàn)在是一頁(yè)12個(gè)專(zhuān)輯,所以第二頁(yè)是offset=12,第三頁(yè)offset=24,以此類(lèi)推。。。

一共9頁(yè),一頁(yè)12個(gè),也不到120個(gè)。So... ... 改一下url 就不用翻頁(yè)了!!

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

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

          
        

下面就開(kāi)始爬蟲(chóng)代碼了。
這里我們會(huì)用到上一篇博文中寫(xiě)好的幾個(gè)工具方法:

          
            '''
在學(xué)習(xí)過(guò)程中有什么不懂得可以加我的
python學(xué)習(xí)交流扣扣qun,934109170
群里有不錯(cuò)的學(xué)習(xí)教程、開(kāi)發(fā)工具與電子書(shū)籍。
與你分享python企業(yè)當(dāng)下人才需求及怎么從零基礎(chǔ)學(xué)習(xí)好python,和學(xué)習(xí)什么內(nèi)容。
'''
    def save_img(self, url, file_name): ##保存圖片
        print('開(kāi)始請(qǐng)求圖片地址,過(guò)程會(huì)有點(diǎn)長(zhǎng)...')
        img = self.request(url)
        print('開(kāi)始保存圖片')
        f = open(file_name, 'ab')
        f.write(img.content)
        print(file_name,'圖片保存成功!')
        f.close()
 
    def request(self, url):  #封裝的requests 請(qǐng)求
        r = requests.get(url)  # 像目標(biāo)url地址發(fā)送get請(qǐng)求,返回一個(gè)response對(duì)象。有沒(méi)有headers參數(shù)都可以。
        return r
 
    def mkdir(self, path):  ##這個(gè)函數(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): #獲取文件夾中的文件名稱(chēng)列表
        pic_names = os.listdir(path)
        return pic_names
          
        

OK, 開(kāi)始我們的爬蟲(chóng)邏輯部分:

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

看下面的網(wǎng)頁(yè)結(jié)構(gòu),iframe的id是“g_iframe”:

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

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

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

根據(jù)上圖的網(wǎng)頁(yè)結(jié)構(gòu)可以看出,所有的專(zhuān)輯信息都在ul 標(biāo)簽里面,每一個(gè)專(zhuān)輯在一個(gè)li 標(biāo)簽里。li 標(biāo)簽中包含了圖片url、專(zhuān)輯名字、以及專(zhuān)輯時(shí)間。

抓取其中的內(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ù)的,所以要過(guò)濾寬高參數(shù):
http://p4.music.126.net/pLA1G...

把問(wèn)號(hào)后面的參數(shù)過(guò)濾掉:

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

圖片命名邏輯:專(zhuān)輯時(shí)間 + 專(zhuān)輯名。

專(zhuān)輯名可能有一些特殊字符,需要替換掉!

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

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

          
            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('開(kāi)始切換文件夾')
        os.chdir(self.folder_path)  # 切換路徑至上面創(chuàng)建的文件夾
 
        file_names = self.get_files(self.folder_path)  # 獲取文件夾中的所有文件名,類(lèi)型是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)
          
        

其實(shí)相對(duì)于上篇博文的例子,這個(gè)爬蟲(chóng)的邏輯部分還是挺簡(jiǎn)潔的。

          
            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" #請(qǐng)求網(wǎng)址
        self.folder_path = "C:\D\TheBeatles" #想要存放的文件目錄
 
    def save_img(self, url, file_name):  ##保存圖片
        print('開(kāi)始請(qǐng)求圖片地址,過(guò)程會(huì)有點(diǎn)長(zhǎng)...')
        img = self.request(url)
        print('開(kāi)始保存圖片')
        f = open(file_name, 'ab')
        f.write(img.content)
        print(file_name, '圖片保存成功!')
        f.close()
 
    def request(self, url):  # 封裝的requests 請(qǐng)求
        r = requests.get(url)  # 像目標(biāo)url地址發(fā)送get請(qǐng)求,返回一個(gè)response對(duì)象。有沒(méi)有headers參數(shù)都可以。
        return r
 
    def mkdir(self, path):  ##這個(gè)函數(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):  # 獲取文件夾中的文件名稱(chēng)列表
        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('開(kāi)始切換文件夾')
        os.chdir(self.folder_path)  # 切換路徑至上面創(chuàng)建的文件夾
 
        file_names = self.get_files(self.folder_path)  # 獲取文件夾中的所有文件名,類(lèi)型是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í)行結(jié)果:

看看文件夾里面什么樣:


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對(duì)您有幫助就好】

您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長(zhǎng)會(huì)非常 感謝您的哦!!!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 扶绥县| 青浦区| 无锡市| 湖州市| 南木林县| 曲沃县| 五河县| 古田县| 闵行区| 泰和县| 四子王旗| 阿瓦提县| 彭阳县| 绥宁县| 丹东市| 米易县| 阿拉善右旗| 成安县| 小金县| 方山县| 鹤峰县| 青铜峡市| 吉林市| 新沂市| 保德县| 博白县| 张掖市| 开化县| 安阳县| 蓝田县| 渝北区| 丰镇市| 阳春市| 湄潭县| 自贡市| 荣成市| 徐州市| 格尔木市| 岚皋县| 正宁县| 慈利县|