酷狗音乐的爬取,基于python,从无到有完整教程-下:功能代码讲解

4 篇文章 0 订阅
3 篇文章 1 订阅

酷狗音乐的爬取,从无到有完整教程-下:功能代码讲解

是的我又回来了,这次是代码的讲解哦。

参数项生成

上一章我们提到,在包含了歌曲url,歌曲信息的请求中,有几个参数项的值是随机数就可以,但是,你仔细看,虽然是随机数,有些参数项的值就是数字,有些就是数字和字符混合,所以这里我们不仅要生成随机数,还要分类生成不同的随机数。
给大家看一下我写的的生成函数(目前是我感觉最明了的方法了>_<)

在这里插入图片描述
调用这个函数需要提供两个参数,一是DataType,也就是要生成的类型,是纯字符还是纯数字还是混合,还有一个就是length,也就是生成的字符串长度,这个很好理解就不多说嘻嘻

请求中等待时间的随机

由于在请求网页数据的时候需要等待网页加载完在获得网页当前的元素,所以就会需要一个等待时间,但是固定的等待时间,容易让浏览器觉得你是个假人,不能很好的伪装(我也是从别人的blog看的哈哈),从而让服务器抹掉你的cookies或者ip什么的,嗯对没错,就是这样>//>
延时后再加个随机秒数就好了

def gen_random_sec(fix = 1):
    a = random.random()
    a = a + fix
    return a 

创建虚拟浏览器并获取各类榜单的href

用selenium库中的webdriver来创建

edge_driver = r"E:\venv\Lib\site-packages\selenium\webdriver\msedge\msedgedriver.exe"
# 需要把该路径加到windows运行环境中
browser = webdriver.Edge(executable_path=edge_driver)

请求酷狗排行榜页面

def get_category_rank(url='https://www.kugou.com/yy/html/rank.html'):
    browser.get(url)
    # 请求页面,即浏览器打开该页面
    time.sleep(gen_random_sec())
    print(gen_random_sec())
    data = browser.page_source
    # 获取当前页面的html组成元素
    soup = BeautifulSoup(data, 'html.parser')
    # 网页带有16进制,需解码,soup就等于网页的元素了,可以用来提取想要的数据

    rank_group = soup.findAll('a',attrs={'hidefocus':'true'})
    # 这里抓取的就是左边的各类排行榜元素,attrs={}里面是他们的元素属性
    category_rank = []
    for i, value in enumerate(rank_group):
    # 收集所有类别榜单的href
        category_rank.append(value.attrs['href'])
    return category_rank

在这里插入图片描述

抓取各类排行榜的歌曲播放页面href

这个直接根据attrs特征抓就完事了,上码

def get_href_group(search_html):
    browser.get(search_html)
    time.sleep(gen_random_sec())
    print(gen_random_sec())
    data = browser.page_source
    soup = BeautifulSoup(data, 'html.parser')
    # 网页带有16进制,需解码
    href_list = soup.findAll('a', attrs="data-active=\"playDwn\"", class_="pc_temp_songname")
    href_group = []
    # 将歌曲播放页面的href收集起来
    for i, value in enumerate(href_list):
        href_group.append(value.attrs['href'])
    return href_group

在这里插入图片描述
还有不知道怎么定位的小伙伴,点击这个图标之后再把你的鼠标位置移到你想要定位的地方就可以自动定位到他的网页元素组成部分

在这里插入图片描述

跳转到歌曲播放页面并提取参数项hash和album_id

def get_data_Url(href):
    album_data = [0]
    browser.get(href)
    time.sleep(gen_random_sec())
    a = browser.current_url
    album_data = re.split("\.html#|&",a)
    # ['', 'hash=AF2C86AE1836546B32778C18A2F37234', 'album_id=37515535']
    album_data[0] = {"hash":album_data[-2],"album_id":album_data[-1]}
    str1 = gen_random_str("int",19)
    str2 = gen_random_str("int",13)
    str3 = gen_random_str("mix",24)
    str4 = gen_random_str("mix",32)
    str5 = gen_random_str("int",13)
    # str1,2,3,4,5都是之前说的参数项值(可随机生成)
    data_url = "https://wwwapi.kugou.com/yy/index.php?r=play/getdata&callback=jQuery"+str1+"_"+str2+"&"+album_data[0]['hash']+"&dfid="+str3+"&mid="+str4+"&platid=4&"+album_data[0]['album_id']+"&_="+str5+""

    return data_url

有人就说,博主你不是说hash包含在href里面吗,为什么不直接提取就好了,还要加一句browser.current_url来获取当前网页的url然后再提取hash,id,其实你可以仔细看看,你在上一步提取的href,跳转过来等一会就变了,不信你看下面
在这里插入图片描述
—这是分割线—
在这里插入图片描述
仔细看确实是不一样的

提取信息和下载的url

在这里插入图片描述

def get_playurl(data_url):
    data = requests.get(data_url)
    data = requests.get(data_url).text
    a = re.split("\(|\)", data)
    # 爬取回来的为response格式,需要用split提取其中json数据,然后再用json.loads(似乎还会帮你解码中文)将json转化成字典
    data_dict=json.loads(a[1])
    play_url=data_dict['data']['play_url']
    avatar=data_dict['data']['authors'][0]['avatar']
    author_name=data_dict['data']['author_name']
    audio_name=data_dict['data']['audio_name']
    album_name=data_dict['data']['album_name']
    song_name=data_dict['data']['song_name']
    b={"play_url":play_url,"avator":avatar,"author_name":author_name,"audio_name":audio_name,"album_name":album_name,"song_name":song_name}
    song_data.append(b)

json.loads可以帮我们把字符转为字典(符合字典格式的字符串),方便我们提取数据

下载至本地

def download(song_data):
    for i in song_data:
        FileName = FileRoot + '\\' + i['audio_name'] + '.mp3'
        # 这个是你的保存路径
        DownloadUrl = i['play_url']
        try:
            with open(FileName, 'wb') as f:
                f.write(requests.get(DownloadUrl).content)
                # 此句作用等于下载网页的内容,因为这是音频流,所以等于直接下载音乐
            #SetMp3Info(FileName, i)
            print(i['audio_name']+'-----下载成功')
        except:
            print('该音频无法正常下载---' + i['audio_name'] + ':' + DownloadUrl)

有人会好奇with open(FileName, ‘wb’) as f:中的wb代表什么,其实我一开始也不知道,只会用,后面我去查了下,才发现有一定的学问在里头。具体看这,来自别人的blog
在这里插入图片描述
-----------------------------------------这是分割线---------------------------------------------
到此对酷狗的爬取就完结了,我诚挚感谢各位能人异士在各个网站上对我的帮助,过程中很多的报错,很多的奇怪现象我都遇到过,有时候单靠我一人还真不知道从何下手。
在此给大家安利一个网站,以后你遇到什么莫名其妙的报错,一般在这上面都可以找到你想要的答案
https://stackoverflow.com/
在这里插入图片描述

关于整篇的代码,我已上传,欢迎下载交流

  • 10
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值