??大家好,我是不溫卜火,是一名計算機學院大資料專業大三的學生,昵稱來源于成語—
不溫不火,本意是希望自己性情溫和,作為一名互聯網行業的小白,博主寫博客一方面是為了記錄自己的學習程序,另一方面是總結自己所犯的錯誤希望能夠幫助到很多和自己一樣處于起步階段的萌新,但由于水平有限,博客中難免會有一些錯誤出現,有紕漏之處懇請各位大佬不吝賜教!暫時只在csdn這一個平臺進行更新,博客主頁:https://buwenbuhuo.blog.csdn.net/,
PS:由于現在越來越多的人未經本人同意直接爬取博主本人文章,博主在此特別宣告:未經本人允許,禁止轉載!!!
目錄
- 一、URL分析
- 二、區域代碼實作
- 2.1 獲取所有的歌手型別
- 2.2 爬歌手資料
- 2.3 發現問題
- 三、完整代碼
- 四、運行結果

前幾篇博文,爬取的都是比較常規的網站,大家是不是都有點膩了呢?如果大家感覺膩了的話,博主此次帶來的比較新奇的內容,如果大家沒有膩的話,當我沒說,話不多說,網抑云時間到了!

一、URL分析
在此,博主爬取的是網易云網頁版,因為一般網頁版都是最好爬取的,不要問我為什么,問就是不會!

網易云網頁版鏈接:https://music.163.com/
歌手資訊鏈接:https://music.163.com//discover/artist

但是由上圖我們可以看出,雖然直接給出了網頁鏈接,但是我們通過查看網頁源代碼,發現我們想要爬取的資訊并沒有在這個網頁中,
這個時候,我們就需要通過Sreach查找歌手資訊,從而得到我們所需要的各種資訊,

我們首先就以薛之謙為例

通過上圖,我們可以知道我們所需要的爬取內容的網址:

我們可以多嘗試幾次,然后就會發現每個分類代表其中一個id

規律來了,那么我們是不是就可以使用xpath進行決議提取了呢? 我們可以先試驗一下:

我們發現這個頁面是不能直接使用xpath進行決議得,xpath只能決議html標簽,因為該網頁攜帶有iframe標簽,內容有不規則內容,

既然出現問題了,那么我們首先要想的就是要解決xpath不能進行決議這一問題,
通過驗證我們發現,雖然在頁面插件中不能訪問,但是我們發現向另一個url發送請求依然可以獲取資料,且里面沒有iframe,可以直接使用xpath,
測驗代碼如下:
import requests
from lxml import etree
headers={
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36',
}
base_url = "https://music.163.com/discover/artist/cat?id=1001"
response = requests.get(url=base_url, headers=headers)
html = response.content.decode("utf-8")
print(html)
我們通過查找iframe,發現里面沒有包含iframe,這里就可以直接使用xpath進行決議了

查找華語男歌手

先把華語男歌手這一部分復制出來
<li><a href="/discover/artist/cat?id=1001"
class="cat-flag z-slt"
data-cat="1001">華語男歌手</a>
</li>
我們先來嘗試使用xpath進行決議
# 只有華語男歌手
ret = etree_obj.xpath('//a[@class="cat-flag z-slt"]/text()')
print(ret)

🆗,我們發現,可以獲取到華語男歌手,那么我們嘗試獲取所有歌手的分類
# 所有歌手
ret = etree_obj.xpath('//a[@class="cat-flag"]/text()')
print(ret)

獲取了分類之后,我們就可以獲取到每個類所對應的鏈接
# 鏈接
ret = etree_obj.xpath('//a[@class="cat-flag"]/@href')
print(ret)

下面就開始看看拼接的URL能否正常打開
"""
華語男歌手: https://music.163.com/discover/artist/cat?id=1001
華語女歌手: https://music.163.com/discover/artist/cat?id=1002
"""

🆗,我們發現正是我們想要爬取內容的URL,至于前兩個推薦歌手以及入住歌手為什么不爬取,是因為推薦的這些歌手都在我們要爬取的分類之中,如果全部爬取,會出現重復現象,

二、區域代碼實作
2.1 獲取所有的歌手型別
def get_type_url():
"""獲取所有的歌手型別"""
types = []
html = parse_url(start_url)
etree_obj =parse_html(html)
type_name_list = etree_obj.xpath('//a[@class="cat-flag"]/text()')
# print(type_name_list)
type_url_list = etree_obj.xpath('//a[@class="cat-flag"]/@href')
data_zip = zip(type_name_list[1:],type_url_list[1:])
for data in data_zip:
type = {}
type["name"] = data[0]
type["url"] = data[1]
types.append(type)
return types

2.2 爬歌手資料
- 1. 分析

把此部分的原始碼拿出來
<a href=" /artist?id=5781" class="nm nm-icn f-thide s-fc0" title="薛之謙的音樂">薛之謙</a>
<a class="f-tdn" href="/user/home?id=97137413" title="薛之謙的個人主頁"><i class="u-icn u-icn-5"></i></a>
- 2. 代碼
def get_data(url, type_name):
"""爬歌手資料"""
item = {
"type": type_name,
"name": "",
"url": ""
}
html = parse_url(url)
etree_obj = parse_html(html)
artist_name_list = etree_obj.xpath('//a[@class="nm nm-icn f-thide s-fc0"]/text()')
artist_url_list = etree_obj.xpath('//a[@class="nm nm-icn f-thide s-fc0"]/@href')
data_zip = zip(artist_name_list, artist_url_list)
for data in data_zip:
item["name"] = data[0]
item["url"] = base_url + data[1][1:]
items.append(item)

我們通過觀察,發現歌手正好是100個,說明我們已經成功拿到資料了,

2.3 發現問題
- 1.分析

經過上述程序,我們已經把資料拿全了,但是我們經過查看,發現我們拿的資料并不準確,我們發現我們拿的資料應該是從A到Z才對,
并且通過點擊,我們也是發現有規律的,規律如下
https://music.163.com/#/discover/artist/cat?id=1001&initial=65
https://music.163.com/#/discover/artist/cat?id=1001&initial=66
https://music.163.com/#/discover/artist/cat?id=1001&initial=90
通過上述的規律,我們發現還要在我們已經獲取的URL的基礎上再加上&initial=(65,90)才行
- 2. 實作
def start():
"""開始爬蟲"""
types = get_type_url()
# print(types)
for type in types:
# url = base_url+type["url"]
# url還不夠完整
# print(url)
for i in range(65,91):
url = "{}{}&initial={}".format(base_url,type["url"],i)
print(url)
get_data(url, type["name"])


三、完整代碼
# encoding: utf-8
'''
@author 李華鑫
@create 2020-10-08 8:27
Mycsdn:https://buwenbuhuo.blog.csdn.net/
@contact: 459804692@qq.com
@software: Pycharm
@file: 作業:網易云音樂.py
@Version:1.0
'''
"""
華語男歌手: https://music.163.com/discover/artist/cat?id=1001
華語女歌手: https://music.163.com/discover/artist/cat?id=1002
"""
import requests
import random
import csv
import time
from lxml import etree
# num = [1001,1002,1003,2001,2002,2003,6001,6002,6003,7001,7002,7003,4001,4002,4003]
base_url = "https://music.163.com/"
# start_url = "https://music.163.com/discover/artist/cat?id=1001"
start_url = "https://music.163.com/discover/artist/"
headers={
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36',
}
items = []
def parse_url(url):
"""決議url,得到回應內容"""
time.sleep(random.random())
response = requests.get(url=url,headers=headers)
return response.content.decode("utf-8")
def parse_html(html):
"""使用xpath決議html,回傳xpath物件"""
etree_obj = etree.HTML(html)
return etree_obj
def get_type_url():
"""獲取所有的歌手型別"""
types = []
html = parse_url(start_url)
etree_obj =parse_html(html)
type_name_list = etree_obj.xpath('//a[@class="cat-flag"]/text()')
# print(type_name_list)
type_url_list = etree_obj.xpath('//a[@class="cat-flag"]/@href')
data_zip = zip(type_name_list[1:],type_url_list[1:])
for data in data_zip:
type = {}
type["name"] = data[0]
type["url"] = data[1]
types.append(type)
return types
def get_data(url, type_name):
"""爬歌手資料"""
item = {
"type": type_name,
"name": "",
"url": ""
}
html = parse_url(url)
etree_obj = parse_html(html)
artist_name_list = etree_obj.xpath('//a[@class="nm nm-icn f-thide s-fc0"]/text()')
artist_url_list = etree_obj.xpath('//a[@class="nm nm-icn f-thide s-fc0"]/@href')
data_zip = zip(artist_name_list, artist_url_list)
for data in data_zip:
item["name"] = data[0]
item["url"] = base_url + data[1][1:]
items.append(item)
def save():
"""將資料保存到csv中"""
with open("./wangyinyun.csv", "a", encoding="utf-8") as file:
writer = csv.writer(file)
for item in items:
writer.writerow(item.values())
def start():
"""開始爬蟲"""
types = get_type_url()
# print(types)
for type in types:
# url = base_url+type["url"]
# url還不夠完整
# print(url)
for i in range(65,91):
url = "{}{}&initial={}".format(base_url,type["url"],i)
print(url)
get_data(url, type["name"])
save()
# exit()
if __name__ == '__main__':
start()
"""測驗代碼"""
# start_url = "https://music.163.com/discover/artist/cat?id=1001&initial=65" a _ z
# response = requests.get(url=base_url,headers=headers)
# # print(response.content.decode("utf-8"))
# html = response.content.decode("utf-8")
# print(html)
# etree_obj = etree.HTML(html)
# # 只有華語男歌手
# # ret = etree_obj.xpath('//a[@class="cat-flag z-slt"]/text()')
# # 所有歌手
# ret = etree_obj.xpath('//a[@class="cat-flag"]/text()')
# print(ret)
# print(len(ret))
#
# # 鏈接
# ret = etree_obj.xpath('//a[@class="cat-flag"]/@href')
# print(ret)
"""
<li><a href="/discover/artist/cat?id=1001"
class="cat-flag z-slt"
data-cat="1001">華語男歌手</a>
</li>
https://music.163.com/discover/artist/cat?id=1001&initial=65
"""

四、運行結果


美好的日子總是短暫的,雖然還想繼續與大家暢談,但是本篇博文到此已經結束了,如果還嫌不夠過癮,不用擔心,我們下篇見!

??好書不厭讀百回,熟讀課思子自知,而我想要成為全場最靚的仔,就必須堅持通過學習來獲取更多知識,用知識改變命運,用博客見證成長,用行動證明我在努力,
??如果我的博客對你有幫助、如果你喜歡我的博客內容,請“點贊” “評論”“收藏”一鍵三連哦!聽說點贊的人運氣不會太差,每一天都會元氣滿滿呦!如果實在要白嫖的話,那祝你開心每一天,歡迎常來我博客看看,
??碼字不易,大家的支持就是我堅持下去的動力,點贊后不要忘了關注我哦!


轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/195304.html
標籤:其他

