本文的文字及圖片來源于網(wǎng)絡(luò),僅供學(xué)習(xí),、交流使用,不具有任何商業(yè)用途,如有問題請及時聯(lián)系我們以作處理。 作者:阿里波特 來源:CSDN Python爬蟲,、數(shù)據(jù)分析,、網(wǎng)站開發(fā)等案例教程視頻免費在線觀看 https://space.bilibili.com/523606542 一、前言前文說過我的設(shè)計師小伙伴的設(shè)計需求,,他想做一個披頭士樂隊歷年專輯的瀑布圖,。 通過搜索,發(fā)現(xiàn)網(wǎng)易云音樂上有比較全的歷年專輯信息加配圖,,圖片質(zhì)量還可以,,雖然有大有小。 我的例子怎么都是爬取圖片,?(誰讓你總是跟設(shè)計師小伙伴一起玩耍,。。,。)看來圖片對于設(shè)計師來說還是有著很深的情節(jié),,那就看他用這些圖片能做出什么樣的作品啦,,期待一下,,后續(xù)會展示一下他的作品。 其實爬取網(wǎng)易云音樂跟之前爬取的網(wǎng)站稍稍有點不同,,當(dāng)然,,爬蟲寫的多了就覺得套路都是固定的,,見招拆招而已。 二,、運行環(huán)境我的運行環(huán)境如下:
三、實戰(zhàn)上面提到過,,網(wǎng)易云音樂的網(wǎng)頁跟普通的網(wǎng)頁相比主要有兩點不同:
廢話不多說,看實際操作步驟: 在右上角的搜索框中輸入“The Beatles”,,然后會有一個下拉選項,,選擇歌手 The Beatles (紅框中的內(nèi)容)。 然后看到如下頁面,,選擇紅框中的“所有專輯”,,點擊。 這樣就會看見所有的專輯列表,,以及下方的翻頁按鈕,。 我們需要的就是所有專輯的圖片、專輯名和專輯出版時間,??吹竭@就可以構(gòu)想一下爬蟲的爬取邏輯了。定位到該頁面,,然后獲取頁碼,,然后挨個請求頁面來爬取頁面中的內(nèi)容。 點擊第二頁后,,看到上面的地址欄?。?!看到這個地址欄我都懶得翻頁了,。。,。 limit 參數(shù)是限制一個頁面加載專輯的個數(shù) 一共9頁,一頁12個,,也不到120個,。So… … 改一下url 就不用翻頁了!,! 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) # 像目標(biāo)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 框架相當(dāng)于在頁面中又加載了一個頁面,需要使用Selenium 的 switch_to.frame() 方法加載(官網(wǎng)給的方法是switch_to_frame(),,但是IDE提醒使用前面的方法替代該方法),。 看下面的網(wǎng)頁結(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)頁結(jié)構(gòu)可以看出,所有的專輯信息都在ul 標(biāo)簽里面,,每一個專輯在一個li 標(biāo)簽里。li 標(biāo)簽中包含了圖片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ù): 把問號后面的參數(shù)過濾掉: end_pos = album_img.index('?') #找到問號的位置 album_img_url = album_img[:end_pos] #截取問號之前的內(nèi)容
圖片命名邏輯:專輯時間 + 專輯名。 再使用上一篇博文例子中的去重邏輯,修改后的爬蟲邏輯部分如下: 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) # 像目標(biāo)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í)行結(jié)果: 四,、后語這個實戰(zhàn)很好的運用了咱們之前講解的知識:
|
|