好啦好啦,那我們來拉開我們的爬蟲之旅吧~~~
這一只小爬蟲是爬取酷狗TOP500的,使用的爬取手法簡單粗暴,目的是幫大家初步窺探爬蟲長啥樣,后期會慢慢變得健壯起來的。
環境配置
在此之前需要下載一個谷歌瀏覽器,下好后由於谷歌搜索是需要FQ的,可設置打開網頁為百度來使用
我們用到的是bs4,要求這兩個庫來提取,這是簡稱,全稱是BeautifulSoup庫。中文名也叫“美麗的湯”,安裝也很簡單。
:cmd命令行(win + r),輸入pip install bs4完成安裝,如下圖:

請求庫同樣,pip安裝請求
可能遇到的安裝錯誤
如果執行pip install bs4后報錯為“ pip不是重置的命令”
這是因為沒有把pip的路徑加入“環境變量”,加入環境變量即可
構造請求網址
我們是爬取酷狗音樂TOP500的'音樂名','歌手','歌名','播放時間'這幾個數據網址如下:
https://www.kugou.com/yy/rank/home/1-8888.html?from=rank
:后只能看到前22名的數據,如下:

網址也叫url,唯一資源定位符,我們觀察url如下幾個細分:
https:傳輸協議,一般都是http或https
www.kugou.com:為域名
yy / rank / home / abs:為域名下的子網頁
.html:代表此網頁是靜態的,后面會講
?:問號后面的一般都是一些請求參數
我們可以看到,其中有一個1-8888這個參數,打開上述網址后我們只能看到前22首歌,想繼續查看后面的歌曲就得翻頁,就像“淘寶”那樣查看下一頁商品需要翻頁,這里也是一樣的道理,把1-8888改成2-8888,就會看到下一頁的22首歌,如下:

我們翻到第500首音樂那一頁,可以看到頁碼如下有23頁:

到這里我們我們需要提取的數據就知道在哪里了。
在知道了有多少頁以及url的含義后,通過以下代碼構造所有的url:
urls = ['https://www.kugou.com/yy/rank/home/{}-8888.html?from=rank' .format(str(i)) for i in range(1, 24)]
構造請求頭
什么是請求頭?
別人網頁區別是人還是機器訪問的一種手段,我們設置請求頭為瀏覽器的請求頭,對方就會認為我們是人為的訪問,從而不會反爬,當然這只是最簡單的一種防反爬的手段,一般我們都會帶上,代碼如下:
headers = { 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/53\ 7.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36' }
這並不是一個一個手敲的!!!
我們來看看它在哪里,按F12出現開發者工具,再按F5刷新出現如下圖:

按照紅線提示,找到用戶代理

最后復制粘貼得到上面的代碼
請求訪問網頁
response = requests.get(url, headers=headers) if response.status_code == 200: return response.text else: return
響應= request.get(URL,headers = headers)
使用請求庫的get方法,去訪問網頁,第一個參數為網址,第二個參數為請求頭,請求結果賦值給變量response,其中里面有很多結果,狀態響應碼,網頁二進制代碼,二進制等
response.status_code == 200
調用請求結果響應中的status_code查看請求狀態碼,200代表請求成功,就返回,否則返回一個None,狀態碼一般有2xx,4xx,3xx,5xx,分別代表請求成功,客戶端訪問失敗,重定向,服務器問題。
返回response.text
返回響應結果的text,代表返回網頁html源碼
解析網頁
在上面返回了一個響應后,我們需要解析網頁html源碼,需要結構化,可以提取
html = BeautifulSoup(html)
提取數據
我們來提取排名,鼠標放在排名這個元素這里,右鍵檢查:

li:nth-child(1)需要改成li,因為nth-child(在右邊可以看到一串二進制。其中有個高兩個,就是剛剛那個排名的元素,快捷跟隨提示選擇然后復制過去,其中li:nth-child(1) 1)是獲取li標簽下的一條數據,我們是要獲取這一頁的所有排名

# 排名 ranks = html.select('#rankWrap > div.pc_temp_songlist > ul > li > span.pc_temp_num')
同樣的方法提取歌手歌名,播放時間
# 歌手 + 歌名 names = html.select('#rankWrap > div.pc_temp_songlist > ul > li > a') # 播放時間 times = html.select('#rankWrap > div.pc_temp_songlist > ul > li > span.pc_temp_tips_r > span')
獲得數據
for r,n,t in zip(ranks,names,times): r = r.get_text().replace('\n','').replace('\t','').replace('\r','') n = n.get_text() t = t.get_text().replace('\n','').replace('\t','').replace('\r','')
用了zip函數,意思是把對應的排名,歌名歌手,播放時間打包,可以這樣理解zip函數的結果是一個列表[(排名,歌手歌名,播放時間),(排名,歌手歌名,播放時間)。。。。。]
每一次循環的r,n,t一次對應元組中的元素
get_text()
我們提取到的是這個數據所在的標簽信息,並不是實際數據,所以需要使用get_text()獲得實際數據
.replace('\ n','')。replace('\ t','')。replace('\ r','')
去掉實際數據中多余的字符串
最后把數據打包成字典打印
結束
到這里我們的關鍵步驟就完成了,大家好好理解一下,很容易的。
在這里說一下,這種提取方式是不會常見的,因為效果很不健壯,可能過幾天被人網頁改了改結構,就不能使用了,這里只是讓大家初步了解一下爬蟲的大致提取流程,后面會使用其他更健壯的方法的。
運行結果:

最終代碼
import requests import time from bs4 import BeautifulSoup def get_html(url): ''' 獲得 HTML ''' headers = { 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/53\ 7.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36' } response = requests.get(url, headers=headers) if response.status_code == 200: return response.text else: return def get_infos(html): ''' 提取數據 ''' html = BeautifulSoup(html) # 排名 ranks = html.select('#rankWrap > div.pc_temp_songlist > ul > li > span.pc_temp_num') # 歌手 + 歌名 names = html.select('#rankWrap > div.pc_temp_songlist > ul > li > a') # 播放時間 times = html.select('#rankWrap > div.pc_temp_songlist > ul > li > span.pc_temp_tips_r > span') # 打印信息 for r,n,t in zip(ranks,names,times): r = r.get_text().replace('\n','').replace('\t','').replace('\r','') n = n.get_text() t = t.get_text().replace('\n','').replace('\t','').replace('\r','') data = { '排名': r, '歌名-歌手': n, '播放時間': t } print(data) def main(): ''' 主接口 ''' urls = ['https://www.kugou.com/yy/rank/home/{}-8888.html?from=rank' .format(str(i)) for i in range(1, 24)] for url in urls: html = get_html(url) get_infos(html) time.sleep(1) if __name__ == '__main__': main()
