Python 網絡爬蟲 網易雲歌單篩選

本文章主要是做一個網絡爬蟲的實戰練習。一是能夠對一些爬蟲框架有一個初步瞭解,二是可以練練手,可以做一些簡單的網絡爬蟲項目,達到舉一反三的效果,有助於以後深入理解學習更復雜的爬蟲項目。

所謂爬蟲,就是依據一些規則,對網絡上零散的信息進行索引抓取。像百度,google這類的搜索引擎就是具有一定規則的爬蟲,當隨網絡的迅速發展,搜索引擎無法完全滿足一些需求,這時就需要對需求定製相應的爬蟲規則。

 

環境(框架)

urllib.request:這是Python自帶的庫,不需要單獨安裝,它的作用是爲我們打開url獲取html的內容。

BeautifulSoup:是python的一個第三方庫,它可以從HTML或XML文件中提取數據,並提供一些簡單的、python式的函數用來處理導航、搜索、修改分析樹等功能。

Selenium:主要是用於網站自動化測試。Selenium 庫是一個在WebDriver 上調用的API。WebDriver 有點兒像可以加載網站的瀏覽器,但是它也可以像BeautifulSoup對象一樣用來查找頁面元素,與頁面上的元素進行交互selenium用於爬蟲,主要是用來解決javascript渲染的問題。

Selenium 自己不帶瀏覽器,它需要與第三方瀏覽器結合在一起使用。例如,Chrome, PhantomJS這類瀏覽器。這裏要注意的是,當selenium打開一個網站時,你桌面是可以看到瀏覽器被打開的,這樣對於數據量大的爬蟲無疑是對效率的大打折扣,所以這裏需要使用 ‘無頭’模式打開。這裏不多做贅述,我會在代碼中進行具體操作。

 

實戰

在網易雲的歌單頁面中,有一個分類按鈕,它可以對多種類別的內容進行一次篩選,這裏就實現一些一個簡單的歌單類別篩選,將自己感興趣的歌單的網頁鏈接爬取下來。

這裏要引入一個名詞,動態網頁。所謂的動態網頁,是指跟靜態網頁相對的一種網頁編程技術。靜態網頁,隨着html代碼的生成,頁面的內容和顯示效果就基本上不會發生變化了——除非你修改頁面代碼。而動態網頁則不然,頁面代碼雖然沒有變,但是顯示的內容卻是可以隨着時間、環境或者數據庫操作的結果而發生改變的。這也是爲什麼我們只有同過是用selenium這個類才能正確獲取網頁內容。

 

代碼

import csv
from selenium import webdriver 
from selenium.webdriver.chrome.options import Options 
import re

#網易雲歌單第一頁url
url="https://music.163.com/#/discover/playlist"

##設置headless chrome屬性
chrome_options=Options()
chrome_options.add_argument('--headless')
chrome_options.add_argument('--disable-gpu')
chrome_options.binary_location=r'C:\Program Files (x86)\Google\Chrome\Application\chrome.exe'

#創建webdriver
driver=webdriver.Chrome(chrome_options=chrome_options)
driver_1=webdriver.Chrome(chrome_options=chrome_options)

#創建存放歌單的csv文件
songlists_file=open("Songlist.csv","w",newline="",encoding="utf-8")
#通過csv對象對文件對象進行操作
writer=csv.writer(songlists_file)
writer.writerow(['歌單','鏈接'])

#選擇需要篩選歌單的類型
type=input("1.流行 2.搖滾 3.民謠 4.說唱\n ")
type=int(type)
#通過選擇的類型 生成正則表達式
if type==1:
	pattern=re.compile(r"流行")
elif type==2:
	pattern=re.compile(r"搖滾")
elif type==3:
	pattern=re.compile(r"民謠")
elif type==4:
	pattern=re.compile(r"說唱")
else:
	pattern=None
	
#當前爬取的頁數
page=0
	
if not pattern==None:
	while url !="javascript:void(0)":
		#用webdriver打開url
		driver.get(url)
		#切換到內容
		driver.switch_to.frame("contentFrame")
		#定位歌單
		SongSheet=driver.find_element_by_id("m-pl-container").\
					find_elements_by_tag_name("li")
		#獲取下一頁
		url=driver.find_element_by_css_selector("a.zbtn.znxt").get_attribute("href")
		#對當前頁面的歌單進行篩選
		for each in range(len(SongSheet)):
			#獲取歌單
			songlist=SongSheet[each].find_element_by_css_selector("a.msk")
			#獲取歌單url		
			songlist_url=songlist.get_attribute("href")
			#打開歌單url
			driver_1.get(songlist_url)
			driver_1.switch_to.frame("contentFrame")
			#定位歌單標籤
			tag=driver_1.find_element_by_css_selector("div.tags.f-cb").find_elements_by_tag_name("a")
			for each in range(len(tag)):
				#對標籤內容進行匹配
				if pattern.match(tag[each].find_element_by_tag_name("i").text):
					writer.writerow([songlist.get_attribute("title"),songlist_url])
			
		page+=1
		print(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>num of page: ", page)
#關閉csv文件
songlists_file.close()

結果

注意點

這裏也是我在編寫代碼放的錯,通過driver.get()方法加載網頁後,內容是實時的,也就是說,當你通過內部方法找到網頁元素後,你重新加載其他網頁,將導致之前獲取的網頁元素無法被找到。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章