吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 4183|回复: 28
收起左侧

[Python 原创] Python爬虫实践--爬取网易云音乐

  [复制链接]
Allenxu520 发表于 2023-8-25 09:22
本帖最后由 Allenxu520 于 2023-8-25 09:25 编辑

http://music.163.com/song/media/outer/url?id=xxxx(下载链接,不要问我链接从哪来的。)
id 就是歌曲的id!所以,现在我们爬虫主要的工作就是找到这个id,当然为了更好的保存,也要找到这个歌名!
分析一下,大概是下面三种:#歌曲清单music_list = 'https://music.163.com/#/playlist?id=2412826586'
#歌手排行榜artist_list = 'https://music.163.com/#/artist?id=8325'
#搜索列表 search_list = 'https://music.163.com/#/search/m/?order=hot&cat=全
网易返回的链接,数据是js动态加载,也就是爬虫得到的网页数据和浏览器得到的dom内容和结构不一样!其中,搜索列表爬虫回来的内容,完全得不到歌曲id!!!
如果你只是想下载一首歌,比如静茹-勇气:https://music.163.com/#/song?id=254485,那你直接就用浏览器打开 http://music.163.com/song/media/outer/url?id=254485 就可以了,其实也没必要爬虫!
缺点:由于是无界面浏览器,采用此方案效率极低,如果大批量抓取不推荐,并且还是会出现爬取的部分歌曲无法播放的情况,具体原因我也不清楚。
对于异步请求并且数据在源码中并不存在的,同时也就无法抓取到的数据。
搜索的歌曲变成歌单,比如想下载全部的某一歌手的全部音乐,用手机云音乐搜索,然后全部保存到新建一个歌单,应该也可以(具体没试过,感兴趣的自己尝试)!
注:本文只是技术交流,请不要商业用途或其他~ 如有违反,再次声明一概与本人无关。


源码如下,其他的自己悟。

[Python] 纯文本查看 复制代码
import os
import re
import json
import requests
from lxml import etree


def download_songs(url=None):
    if url is None:
        url = 'https://music.163.com/#/playlist?id=2384642500'

    url = url.replace('/#', '').replace('https', 'http')  # 对字符串进行去空格和转协议处理
    # 网易云音乐外链url接口:http://music.163.com/song/media/outer/url?id=xxxx
    out_link = 'http://music.163.com/song/media/outer/url?id='
    # 请求头
    headers = {
        'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36',
        'Referer': 'https://music.163.com/',
        'Host': 'music.163.com'
    }
    # 请求页面的源码
    res = requests.get(url=url, headers=headers).text

    tree = etree.HTML(res)
    # 音乐列表
    song_list = tree.xpath('//ul[@class="f-hide"]/li/a')
    # 如果是歌手页面
    artist_name_tree = tree.xpath('//h2[@id="artist-name"]/text()')
    artist_name = str(artist_name_tree[0]) if artist_name_tree else None

    # 如果是歌单页面:
    #song_list_tree = tree.xpath('//*[@id="m-playlist"]/div[1]/div/div/div[2]/div[2]/div/div[1]/table/tbody')
    song_list_name_tree = tree.xpath('//h2[contains(@class,"f-ff2")]/text()')
    song_list_name = str(song_list_name_tree[0]) if song_list_name_tree else None

    # 设置音乐下载的文件夹为歌手名字或歌单名
    folder = './' + artist_name if artist_name else './' + song_list_name

    if not os.path.exists(folder):
        os.mkdir(folder)

    for i, s in enumerate(song_list):
        href = str(s.xpath('./@href')[0])
        song_id = href.split('=')[-1]
        src = out_link + song_id  # 拼接获取音乐真实的src资源值
        title = str(s.xpath('./text()')[0])  # 音乐的名字
        filename = title + '.mp3'
        filepath = folder + '/' + filename
        print('开始下载第{}首音乐:{}\n'.format(i + 1, filename))

        try:  # 下载音乐
            #下载歌词
            #download_lyric(title, song_id)

            data = requests.get(src).content  # 音乐的二进制数据

            with open(filepath, 'wb') as f:
                f.write(data)
        except Exception as e:
            print(e)

    print('{}首全部歌曲已经下载完毕!'.format(len(song_list)))


def download_lyric(song_name, song_id):
    url = 'http://music.163.com/api/song/lyric?id={}&lv=-1&kv=-1&tv=-1'.format(song_id)
    # 请求头
    headers = {
        'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36',
        'Referer': 'https://music.163.com/',
        'Host': 'music.163.com'
        # 'Origin': 'https://music.163.com'
    }
    # 请求页面的源码
    res = requests.get(url=url, headers=headers).text
    json_obj = json.loads(res)
    lyric = json_obj['lrc']['lyric']
    reg = re.compile(r'\[.*\]')
    lrc_text = re.sub(reg, '', lyric).strip()

    print(song_name, lrc_text)




if __name__ == '__main__':
    #music_list = 'https://music.163.com/#/playlist?id=2384642500' #歌曲清单
    music_list = 'https://music.163.com/#/artist?id=8325' #歌手排行榜
    # music_list = 'https://music.163.com/#/search/m/?order=hot&cat=全部&limit=435&offset=435&s=梁静茹' #搜索列表
    download_songs(music_list)

免费评分

参与人数 6吾爱币 +12 热心值 +6 收起 理由
ycm520 + 1 + 1 谢谢分享
currys + 1 + 1 谢谢@Thanks!
echoaku + 1 + 1 热心回复!
苏紫方璇 + 7 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
windong + 1 + 1 用心讨论,共获提升!
jojo198365 + 1 + 1 谢谢@Thanks!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

asdq 发表于 2023-8-25 18:49
正在学习中,感谢分享
taoyuanhang 发表于 2023-9-9 08:52
[Python] 纯文本查看 复制代码
with open(f"{input('歌名:')}.mp3",'wb') as i:    
    i.write(__import__('requests').get(f"http://music.163.com/song/media/outer/url?id={input('请输入网址:')[32:]}.mp3").content)
zxsbk 发表于 2023-8-25 09:32
FlintJie 发表于 2023-8-25 10:12
谢谢分享,学习一下
cick 发表于 2023-8-25 10:20
我咋执行了之后,部分歌曲不能播放,下载都下载好了
````
开始下载第49首音乐:可乐戒指.mp3

开始下载第50首音乐:天气预报.mp3

50首全部歌曲已经下载完毕!

Process finished with exit code 0
````
播放有的歌曲不可以播放,比如列表中的【孤单北半球live】等歌曲
richhs 发表于 2023-8-25 10:39
谢谢分享
weiyanli 发表于 2023-8-25 11:36
学习中,感谢分享
fenggod1 发表于 2023-8-25 16:12
感谢分享,代码逻辑很清晰
nbwww 发表于 2023-8-25 18:42
http://music.163.com/song/media/outer/url?id=254485     MS打开404   

是不是要用会员登陆?
xls113355 发表于 2023-8-26 15:55
学习一下,共同进步
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-24 19:48

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表