正在阅读:

[python]喜马拉雅mp3批量下载工具

29,382

最近没啥好听的歌,准备给小虎子补充点好听的,于是就有了喜马拉雅mp3批量下载工具,喜欢的拿去用。

程序说明:

1、使用类写的,简洁明了。

2、取消使用lxml库解析,使用正则表达式获取数据。

3、程序尽可能多的给出了注释,喜欢的拿去研究。

4、可以自动获取专辑下面的所有专辑并下载。

5、取消使用脚本下载,单线程会卡住。

6、脚本只负责解析,剩下的事,交给其它工具下载。

喜马拉雅mp3解析工具:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Date: 2016/10/10
# Created by 独自等待
# 博客 http://www.waitalone.cn/
import requests
import json
import sys
import re
import os

reload(sys)
sys.setdefaultencoding('utf-8')


class ximalaya:
    def __init__(self, url):
        self.url = url  # 传入的专辑URL,类似http://www.ximalaya.com/16960840/album/294567
        self.urlheader = {
            'Accept': 'application/json, text/javascript, */*; q=0.01',
            'X-Requested-With': 'XMLHttpRequest',
            'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.116 Safari/537.36',
            'Content-Type': 'application/x-www-form-urlencoded',
            'Referer': self.url,
            'Cookie': '_ga=GA1.2.1628478964.1476015684; _gat=1',
        }

    def getpage(self):
        '获取分页数方法'
        pagelist = []  # 保存分页数
        try:
            response = requests.get(self.url, headers=self.urlheader).text.encode('utf-8')
        except Exception, msg:
            print u'网页打开出错,请检查!', msg
        else:
            reg_list = [
                re.compile(r"class=\"pagingBar_wrapper\" url=\"(.*?)\""),
                re.compile(r"<a href='(/\d+/album/\d+\?page=\d+)' data-page='\d+'")
            ]
            for reg in reg_list:
                pagelist.extend(reg.findall(response))
        if pagelist:
            return ['http://www.ximalaya.com' + x for x in pagelist[:-1]]
        else:
            return [self.url]

    def analyze(self, trackid):
        '解析真实mp3地址'
        trackurl = 'http://www.ximalaya.com/tracks/%s.json' % trackid
        try:
            response = requests.get(trackurl, headers=self.urlheader).text
        except Exception:
            print trackurl + '解析失败!'
            with open('analyze_false.txt', 'ab+') as false_analyze:
                false_analyze.write(trackurl + '\n')
        else:
            jsonobj = json.loads(response)
            title = jsonobj['title']
            mp3 = jsonobj['play_path']
            filename = title.strip() + '.mp3'
            print filename, mp3
            # todo 调用aria2c.exe实现多线程下载
            # 乱码问题比较难以解决。
            with open('mp3.txt', 'ab+') as mp3file:
                mp3file.write('%s|%s\n' % (filename.decode('utf-8'), mp3))

    def todownlist(self):
        '生成待下载的文件列表'
        if 'sound' in self.url:  # 解析单条mp3
            trackid = self.url[self.url.rfind('/') + 1:]
            self.analyze(trackid)
        else:
            for purl in self.getpage():  # 解析每个专辑页面中的所有mp3地址
                try:
                    response = requests.get(purl, headers=self.urlheader).text
                except Exception, msg:
                    print u'分页请求失败!', msg
                else:
                    ids_reg = re.compile(r'sound_ids="(.+?)"')
                    ids_res = ids_reg.findall(response)
                    idslist = [j for j in ids_res[0].split(',')]
                    for trackid in idslist:
                        self.analyze(trackid)


if __name__ == '__main__':
    print '+' + '-' * 50 + '+'
    print u'\t   Python 喜马拉雅mp3批量下载工具'
    print u'\t   Blog:http://www.waitalone.cn/'
    print u'\t\t Code BY: 独自等待'
    print u'\t\t Time:2016-07-29'
    print '+' + '-' * 50 + '+'
    if len(sys.argv) != 2:
        print u'用法: ' + os.path.basename(sys.argv[0]) + u' 你要下载的专辑mp3主页地址,地址如下:'
        print u'实例: ' + os.path.basename(sys.argv[0]) + ' http://www.ximalaya.com/12495477/album/269179'
        sys.exit()
    ximalaya = ximalaya(sys.argv[1])  # 实例化类
    ximalaya.todownlist()

ximalaya

关于多线程下载:

由于python的多线程下载,我研究的不深,所以实现起来比较麻烦,这里提供一种使用其它工具代替的方法,速度也很快。

http://www.waitalone.cn/aria2c-download.html

请点击上面的链接,去下载cmd下面的多线程工具,aria2c。

1、首先使用脚本解析你要下载的专辑,在cmd下执行如下命令:

ximalaya.py http://www.ximalaya.com/31240537/album/2867229

2、脚本会自动解析,并保存解析结果到 mp3.txt 失败的解析会保存在:analyze_false.txt

3、mp3.txt默认为utf-8格式,请重新保存为ansi格式,否则aria2c保存时文件名乱码。

4、将下面的代码保存为download.bat 然后双击即可自动多线程下载。

for /f "tokens=1,2 delims=|" %%i in (mp3.txt) do aria2c.exe -s 10 -j 10 %%j --out=%%i

MAC OS可以使用下面的方式下载文件:

1、安装axel,可以使用brew install axel

2、使用ximalaya.py生成要下载的文件列表 mp3.txt

3、保存下面的代码为down.sh 增加执行权限,然后运行即可。

#!/bin/bash
filename='mp3.txt'
cat $filename | while read line
do  
    name=$(echo $line|cut -d "|" -f 1)
    url=$(echo $line|cut -d "|" -f 2)
    axel -a -n 10 $url -o "$name"
done  

更新日志:

2016年3月11日更新,支持单条mp3地址解析

2016年3月13日更新,修复mp3总数计算错误, 增加限制下载数量。

2016年7月29日更新,使用正则获取数据,更加易用。

2016年10月10日更新,原有解析失效,重写代码,提高解析速度。

2016年12月8日更新, 增加MAC下多线程下载方法。

2017年5月3日更新, 修正windows下面mp3.txt乱码问题。

目前有:22条访客评论,博主回复14

  1. 文雨
    2016-02-18 16:32

    开始提示
    SyntaxError: ‘gbk’ codec can’t decode bytes in position 15-16: illegal multibyte sequence

    删除了第三行可以正常使用,但是下载的文件名是乱码

  2. Leon
    2016-03-25 11:25

    好东西,谢谢!

    • 独自等待
      2016-03-25 17:12

      虽然没有完全达到我的要求,但是我也懒得改了。

  3. xiao
    2016-04-04 11:48

    用这个工具,下载下来的文件,文件名都是乱的
    将 026 行改成这样 request = urllib2.urlopen(purl, timeout=30).read().decode(‘utf-8’)
    注释掉 085 行,成这样 #title = title.encode(‘gbk’, ‘ignore’) # 编码转换,避免报错
    然后下载下来的文件就是中文名了

    • 独自等待
      2016-04-05 10:28

      我这里测试过N多次,不会乱码的,只是大家在保存的时候,一定要保存成ansi编码的,主要是为了方便windows cmd下面使用,当然,如果有其它平台的出现乱码的话,可以参照你这个使用。

  4. Tian
    2016-07-27 17:05

    第一次用python,下了你的code,运行不过去,出现错误,不知道应该怎么解决,谢谢!

    runfile(‘C:/Users/tjin/Desktop/Python/ximalaya.py’, wdir=’C:/Users/tjin/Desktop/Python’)
    File “C:/Users/tjin/Desktop/Python/ximalaya.py”, line 27
    except Exception, msg:
    ^
    SyntaxError: invalid syntax

    • 独自等待
      2016-07-28 10:58

      可能目标网站修改了代码,等我更新后再来。稍等。

    • XU
      2017-04-30 16:09

      @Tian: 可能是因为您安装/使用了 Python 3.X。这段代码适用于 Python 2.X,不能兼容 3.X。

  5. young king
    2016-09-07 16:08

    怎么开启多线程

  6. XHR
    2016-10-20 10:02

    不会使用啊…

    • 独自等待
      2016-10-21 16:21

      搜索php版的,使用更方便点。然后下载一个windows下的多线程下载工具。

      • 你好
        2016-11-02 11:36

        @独自等待:你好。我是菜鸟啊。根本不懂,可以加个好友,传我一份吗?谢谢啊756712377@qq.com

  7. 老王
    2016-11-28 16:40

    在macbook下木有for 循环,应该用什么命令处理下载呢

    • 独自等待
      2016-11-28 16:52

      MAC我还真没有注意呢,等我晚上回家以后测试一下,然后再回复您,您看可好? 到时我会在此留言给你,你注意查收邮件。

  8. 老王
    2016-11-28 18:12

    自己搞定了,在mac或者linux下,可以这样下载
    #!/bin/bash
    mp3file=$1
    while read -r line
    do
    echo $line
    aria2c -o ${line%|*} ${line##*|}
    done < $mp3file

    • 独自等待
      2016-11-28 18:16

      我了个去,早知道你也在折腾,我就不写了。临时学习了一下bash编程。向兄弟致敬。

    • minifans
      2017-07-11 11:30

      @老王:还是你这个靠谱,还是linux靠谱

  9. uyaboy
    2016-12-11 04:25

    你这python是什么版本的呢

  10. jack
    2017-01-15 15:55

    d:\Jack>ximalaya.py http://www.ximalaya.com/41173090/album/4119967
    File “D:\Jack\ximalaya.py”, line 34
    print u’网页打开出错,请检查!’, msg
    SyntaxError: (unicode error) ‘utf8’ codec can’t decode byte 0xcd in position 0: invalid continuation byte

    转换了格式 提示还是错误

    • 独自等待
      2017-01-25 11:18

      代码内容尽量不要动,然后只是在保存的时候,把文件的格式保存为utf-8格式就能用了。

      • jack
        2017-07-28 23:46

        @独自等待:
        E:\>xmly.py
        Traceback (most recent call last):
        File “E:\xmly.py”, line 6, in
        import requests
        ImportError: No module named requests

        • 独自等待
          2017-08-03 09:06

          先执行pip install requests

          • jack
            2017-08-03 16:25

            @独自等待:
            先安装 python_2.7.12
            添加系统 变量 C:\Python27\ C:\Python27\Scripts
            运行 cmd 测试 python安装是否成功
            安装了python,并且把python的路径配置到path的时候,可以直接在cmd下调用 pip install requests 来进行自动安装。.
            pip install requests

            安装完成后,找喜马拉雅网址 获取mp3.txt 转换文本格式 通过批处理 批量下载到本地
            问题已经解决了。默认 python 没有安装 requests

  11. minifans
    2017-07-11 11:19

    导出很好用,可还是那个多线程下载的,好难用,ariac

  12. 谁人
    2017-11-22 10:08

    这个脚本很好用。
    不会下载的同学可以搜一款软件,IDM,把生成的mp3.txt里的内容复制一下,在软件的“剪贴板里添加批量下载”功能点一下就ok了。

    • 独自等待
      2017-11-24 10:06

      多谢小兄弟的提示,之前没有用IDM,现在发现这个IDM还是很好的。

  13. 松
    2017-12-15 17:27

    我改进了,解决了分页过多的问题,添加了多线程下载以及进度条,重试以及断点继续等功能。
    等于深入学习了一把Python

    • 独自等待
      2017-12-20 16:46

      多谢,请提供一个地址我帮你链接到我这个文章里面。

  14. 小芋头
    2017-12-16 10:02

    下面的out后面增加两个双引号,要不然一些特殊文件名容易出错
    for /f “tokens=1,2 delims=|” %%i in (mp3.txt) do aria2c.exe -s 10 -j 10 %%j –out=”%%i”

  15. 醋溜土豆丝

    脚本非常好用。最近喜马拉雅改版,如地址http://www.ximalaya.com/16960840/album/294567变为http://www.ximalaya.com/qinggan/294567/,脚本似已失灵。博主可否修改一下脚本?

留下脚印,证明你来过。

*

*

流汗坏笑撇嘴大兵流泪发呆抠鼻吓到偷笑得意呲牙亲亲疑问调皮可爱白眼难过愤怒惊讶鼓掌