鱼C论坛

 找回密码
 立即注册
查看: 4209|回复: 4

[技术交流] Python爬取喜马拉雅免费相声音频V2

[复制链接]
发表于 2020-5-2 11:53:07 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 qiuyouzhi 于 2020-5-2 11:54 编辑

Python爬取喜马拉雅免费相声音频V2


本来想在上一个帖子里面写的,但是沉了,所以这里重新发一个。

需求

1,打印第一页的所有相声专辑,并让用户选择。

2,下载此专辑的所有音乐。

思路

目标URL:https://www.ximalaya.com/xiangsheng/xiangsheng/mr132t2722/

好的,先踩点。

审查元素翻一下:

1.png

emmmm,表示并没有找到什么数据,只找到了一张没有用的图片。

这时候怎么办?抓包!

2.png

哦豁,看到了什么?一个开头为 audio 的文件!

点开看看:

3.png

4.png

看到src了吗?直接去看看src对应的值:

5.png

直接可以下载了!

所以,观察刚才的包含下载URL的URL:

https://www.ximalaya.com/revision/play/v1/audio?id=276429286&ptype=1

加粗部分需要一个id,目前我们还没有什么好办法去处理它,所以跳过。

先处理第一部分,爬取第一页的相声专辑:

6.png

看到这一大片的li标签了吗?我们要的内容就在这里面,

代码实现:

  1. def open_url(url):
  2.     headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.129 Safari/537.36'}
  3.     res = get(url, headers=headers)
  4.     return res

  5. def get_xs(res):
  6.     temp = 'https://www.ximalaya.com/xiangsheng'
  7.     html = etree.HTML(res.text)
  8.     name = html.xpath("//*[@class='general-album-list']/div[@class='content']/ul/li/div/a/span/text()")
  9.     href = [temp + each for each in html.xpath("//*[@class='general-album-list']/div[@class='content']/ul/li/div/a[1]/@href")] # 爬下来的链接是个残品,把它和temp组合在一起
  10.     i = 1
  11.     result = {}
  12.     for k in zip(name, href):
  13.         result[i] = k
  14.         i += 1
  15.     return result
复制代码


OK,名字和链接已经保存进字典了,

现在,爬取专辑里面的相声:

7.png

老规矩,都在li标签里面,可以写出代码:

  1. def get_Videourl(nm, hf, page):
  2.     def tempfunc(list1):
  3.         for each in list1:
  4.             yield from each
  5.     vdurl = []  # 存放视频url的列表
  6.     name = []
  7.     for i in range(1, page + 1):
  8.         tempurl = hf + f'p{i}'
  9.         res = open_url(tempurl)
  10.         html = etree.HTML(res.text)
  11.         href = html.xpath('//*[@class="sound-list _Qp"]/ul/li/div[2]/a/@href')
  12.         name.append(html.xpath('//*[@class="sound-list _Qp"]/ul/li/div[2]/a/span/text()'))
复制代码


OK,差不多就这样了,但是,回头看刚才相声里的URL:

https://www.ximalaya.com/xiangsheng/35105051/290954115

诶嘿!后9位,不就是ID号吗?

直接再写一个XPath,提取出来:

  1. def get_Videourl(nm, hf, page):
  2.     def tempfunc(list1):
  3.         for each in list1:
  4.             yield from each
  5.     vdurl = []  # 存放视频url的列表
  6.     name = []
  7.     for i in range(1, page + 1):
  8.         tempurl = hf + f'p{i}'
  9.         res = open_url(tempurl)
  10.         html = etree.HTML(res.text)
  11.         href = html.xpath('//*[@class="sound-list _Qp"]/ul/li/div[2]/a/@href')
  12.         name.append(html.xpath('//*[@class="sound-list _Qp"]/ul/li/div[2]/a/span/text()'))
  13.         ids = [each[-9:] for each in href] # 观察可知,id号在url的后9位,直接切片提出来
  14.         for id in ids:
  15.             vdurl.append('https://www.ximalaya.com/revision/play/v1/audio?id=%s&ptype=1' % id)
  16.     return vdurl, list(tempfunc(name))
复制代码


OK啦!现在就差下载数据了。

把ID搞下来后,下载数据最简单:

  1. {"ret":200,"data":{"trackId":276429286,"canPlay":true,"isPaid":false,"hasBuy":true,"src":"https://aod.cos.tx.xmcdn.com/group77/M09/AE/4F/wKgO1V6DPwKCI8dMANcavfR4wq4296.m4a","albumIsSample":false,"sampleDuration":180,"isBaiduMusic":false,"firstPlayStatus":true}}
复制代码



链接就在"src"里面,下载代码:
  1. def get_Video(vdurl, nm):
  2.     i = 0
  3.     for url in vdurl:
  4.         res = open_url(url).json()
  5.         for each in res:
  6.             if type(res[each]) != int:
  7.                 tempurl = res[each]['src']
  8.                 video = open_url(tempurl)
  9.                 filename = f"{nm[i]}.m4a"
  10.                 print("正在下载:",filename)
  11.                 with open(filename, 'wb') as f:
  12.                     f.write(video.content)
  13.         i += 1
  14.     print("下载完毕!")
复制代码


完整代码:

  1. from requests import get
  2. from lxml import etree
  3. import os

  4. try:
  5.     os.mkdir("Video")
  6.     os.chdir("Video")
  7. except:
  8.     os.chdir("Video")

  9. def open_url(url):
  10.     headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.129 Safari/537.36'}
  11.     res = get(url, headers=headers)
  12.     return res

  13. def get_xs(res):
  14.     temp = 'https://www.ximalaya.com/xiangsheng'
  15.     html = etree.HTML(res.text)
  16.     name = html.xpath("//*[@class='general-album-list']/div[@class='content']/ul/li/div/a/span/text()")
  17.     href = [temp + each for each in html.xpath("//*[@class='general-album-list']/div[@class='content']/ul/li/div/a[1]/@href")]
  18.     i = 1
  19.     result = {}
  20.     for k in zip(name, href):
  21.         result[i] = k
  22.         i += 1
  23.     return result

  24. def get_Videourl(nm, hf, page):
  25.     def tempfunc(list1):
  26.         for each in list1:
  27.             yield from each
  28.     vdurl = []  # 存放视频url的列表
  29.     name = []
  30.     for i in range(1, page + 1):
  31.         tempurl = hf + f'p{i}'
  32.         res = open_url(tempurl)
  33.         html = etree.HTML(res.text)
  34.         href = html.xpath('//*[@class="sound-list _Qp"]/ul/li/div[2]/a/@href')
  35.         name.append(html.xpath('//*[@class="sound-list _Qp"]/ul/li/div[2]/a/span/text()'))
  36.         ids = [each[-9:] for each in href] # 观察可知,id号在url的后9位,直接切片提出来
  37.         for id in ids:
  38.             vdurl.append('https://www.ximalaya.com/revision/play/v1/audio?id=%s&ptype=1' % id)
  39.     return vdurl, list(tempfunc(name))

  40. def get_Video(vdurl, nm):
  41.     i = 0
  42.     for url in vdurl:
  43.         res = open_url(url).json()
  44.         for each in res:
  45.             if type(res[each]) != int:
  46.                 tempurl = res[each]['src']
  47.                 video = open_url(tempurl)
  48.                 filename = f"{nm[i]}.m4a"
  49.                 print("正在下载:",filename)
  50.                 with open(filename, 'wb') as f:
  51.                     f.write(video.content)
  52.         i += 1
  53.     print("下载完毕!")

  54. def main():
  55.     url = 'https://www.ximalaya.com/xiangsheng/xiangsheng/mr132t2722/'
  56.     res = open_url(url)
  57.     result = get_xs(res)
  58.     for i in result:
  59.         for j in range(0,len(result[i]), 2):
  60.             print(i, end = ' ')
  61.             print(result[i][j])

  62.     choice = int(input("请选择您要听的专辑序号:"))
  63.     nm, hf = result[choice]
  64.     page = int(input("请选择您要爬取的页码:"))
  65.     vdurl, nm = get_Videourl(nm, hf, page)
  66.     get_Video(vdurl, nm)


  67. if __name__ == "__main__":
  68.     main()
复制代码

评分

参与人数 1荣誉 +5 收起 理由
乘号 + 5 鱼C有你更精彩^_^

查看全部评分

本帖被以下淘专辑推荐:

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2020-5-2 11:55:09 | 显示全部楼层
沙发
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2020-5-2 12:58:57 | 显示全部楼层
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2020-8-19 21:44:08 | 显示全部楼层
不懂啊·
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-10-15 16:20:50 | 显示全部楼层
我是用selenium来爬取的,不过VIP的爬不了
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-4-26 10:30

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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