美文网首页python热爱者Python新世界
Python采集喜马拉雅音频,想收费那是不可能的,还包含视频教程

Python采集喜马拉雅音频,想收费那是不可能的,还包含视频教程

作者: 48e0a32026ae | 来源:发表于2018-11-03 15:43 被阅读1次

    emmm...不是她

    是它

    前言

    说正经的,前几天给大家看了如何爬取文本以及爬取图片,这儿就来讲讲如何爬取音频(以这个喜马拉雅为例)

    学习Python中有不明白推荐加入交流群

                    号:516107834

                    群里有志同道合的小伙伴,互帮互助,

                    群里有不错的学习教程!

    当我重新跑了一下程序之后,发现...好家伙居然换标签了;这不一下子就来了兴致,与人斗,其乐无穷啊~

    分析

    很多时候不是你不会爬虫,而是你没有一个完整的爬取的思路(当然非常熟练之后,基本上可以根据经验来写啦)

    首页

    全部分类

    我们想爬取的话,可以从这里入手,就是获取这些分类之后,遍历这些分类中的节目,也就是下图中的部分的节目

    而每个节目中,又有如下图这样的一个个播放列表

    所以到这里我们基本的思路就是:

    1、访问全部分类界面后,获取每个分类的链接

    2、进入每个分类,获取每个节目的链接

    3、获取每个节目下的播放列表对应的音频原地址

    4、访问并保存音频

    当然前提我们爬取的是免费的音频,如果想要爬取收费的,说白了你先得开个会员充点钱,再爬取;就我所知的并没有能够让你直接爬取付费的音频或视频,如果可以,也很麻烦,而且可以说,你的这种行为相当有问题

    开始

    首先我初始化基本所需的这些url等,方便在下面的程序中使用

    def __init__(self):

    self.category_Url = 'https://www.ximalaya.com/category/'

    self.base_url = 'https://www.ximalaya.com'

    self.base_api = 'https://www.ximalaya.com/revision/play/tracks?trackIds='

    self.header = {

    'User-Agent': 'your-user-agent'

    }

    self.s = requests.session()

    然后我们从全部分类开始,获取每一个分类的url,拼接之后,再去访问(这里添加了break是由于数量太多,举例而为)

    def geturl(self):

    r = self.s.get(self.category_Url, headers=self.header)

    result = re.findall(r'(.*?)', r.text, re.S)

    url_list = []

    for i in result:

    # 以一个分类为例 - - 有声书中的文学类,若没有break 则可获取全部分类

    second_url = self.base_url + i[0]

    url_list.append(second_url)

    # 获取该分类中全部的页数

    print(second_url, i[1])

    self.get_more_page(second_url)

    break

    接着我们进入到一个分类中,可以看到每个分类大概有34页,所以我们需要遍历这些页;在源代码中我们拿到了最大页数,以此进行循环;而后进入每一页去获取每一页的FM节目的链接 fm_url(可以将获取的节目信息,保存到数据库中,这里我暂未添加,有兴趣的朋友可以实现)

    def get_more_page(self, url):

    r = self.s.get(url, headers=self.header)

    pagenum = re.findall(r'

    r'max="(d+)" class="control-input tthf" value=""/>', r.text, re.S)

    pagenum = int(pagenum[0])

    # 循环获取每一页,这里暂时获取第一页

    for i in range(1, pagenum + 1):

    print(u'第' + str(i) + u'页')

    page_url = url + 'p{}/'.format(i)

    self.get_music_list(page_url)

    # 爬取一页

    break

    def get_music_list(self, url):

    r = self.s.get(url, headers=self.header)

    result = re.findall(

    r'

    r'class="EV"/>.*?',

    r.text, re.S)

    info = []

    # 获取该page中每一个FM的数据信息

    for i in result:

    fm_info = {}

    fm_url = self.base_url + i[0]

    fm_info['url'] = fm_url

    fm_info['picture'] = 'https:' + str(i[1]).replace('amp;', '')

    fm_info['fm_name'] = i[2]

    fm_info['author'] = i[3]

    info.append(fm_info)

    print(fm_info)

    # 获取该FM中的音频信息

    self.get_fm_music(fm_url)

    # 先获取一个FM

    每一个FM节目中有很多的音频,有的可能还有很多页,所以这时也要判断,是否存在多页;若有最大页数则说明需要循环这些页来获取内容,若没有则正常进行下一步

    def get_fm_music(self, fm_url):

    print(fm_url)

    r = self.s.get(fm_url, headers=self.header)

    title = re.findall(r'

    (.*?)

    ', r.text, re.S)

    max_page = re.findall(r'

    r'max="(d+)" class="control-input tthf" value=""/>', r.text, re.S)

    if max_page and max_page[0]:

    for page in range(1, int(max_page[0]) + 1):

    fm_urls = fm_url + '/p{}'.format(page)

    r = self.s.get(fm_urls, headers=self.header)

    self.get_detail(r.text, title)

    else:

    self.get_detail(r.text, title)

    也就是获取列表中每个音频对应的标题、收听数以及发布时间,而最关键的音频原地址,你需要通过浏览器的开发者工具找寻,这里按我之前找出来的是这个链接:

    https://www.ximalaya.com/revision/play/tracks?trackIds={}

    这个 trackIds 就是音频所对应的 id 了

    然后访问这个链接就可以获得包含原地址等在内的诸多信息,将 response 转换为 json 格式可以轻松获得 url(如果存在则说明这个音频不用收费,否则是收费的无法获取)

    最后按对应的音频标题,以其 m4a 格式保存到本地即可(小编是在Ubuntu上更新的,所以windows的朋友只要改下 path 即可)

    def get_detail(self, text, title):

    track_list = re.findall(r'

    .*?'

    r'(.*?)'

    r'(.*?)',

    text, re.S)

    # 爬取一个FM下的每个音频

    for i in track_list:

    print(i)

    # 获取爬取音频所需的trackIds

    music_title = i[0]

    music_url = self.base_url + i[1]

    listen_num = i[2]

    create_time = i[3]

    trackid = str(i[1]).split('/')[3]

    # api中的数据信息

    api = self.base_api + trackid

    print(api)

    r = self.s.get(api, headers=self.header)

    result = r.json()

    src = result['data']['tracksForAudioPlay'][0]

    if src['src']:

    print(u'试听')

    r = self.s.get(src['src'], headers=self.header)

    path = '/home/joel/XiMa/' + title[0]

    e = os.path.exists(path)

    if not e:

    os.mkdir(path)

    fm_path = path + '/{}.m4a'.format(src['trackName'])

    if not os.path.exists(fm_path):

    with open(path + '/{}.m4a'.format(src['trackName']), 'wb') as f:

    f.write(r.content)

    print(u'保存完毕...')

    else:

    print(u'm4a已存在')

    else:

    print(u'需要收费')

    结果

    可能有人问这样的目的是什么?我可以在APP或者网页上的直接听啊!

    诶~对于某些需要的收费的节目,量又很大,你可能会员过期了就无法享受其中的内容,所以可以通过这种方式“下载”

    当然最终要的还是为了让大家理解爬虫的一些思路

    相关文章

      网友评论

        本文标题:Python采集喜马拉雅音频,想收费那是不可能的,还包含视频教程

        本文链接:https://www.haomeiwen.com/subject/slikxqtx.html