ChinaLee 发表于 2020-8-27 21:10:57

这个喜马拉雅的cookies要插在那个位置

如题,自己有喜马拉雅vip,想问一下在哪里添加一个vipcookies可以爬取vip音频。
import requests
import bs4
import json
import os
import openpyxl


class Ximalaya():
    def __init__(self):
      self.url = 'https://www.ximalaya.com'
      self.headers = {
            "user-agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36"}

    # 关键字搜索,返回一个列表 的字典数据
    def search(self, kw):
      res = requests.get(self.url + "/search/" + kw, headers=self.headers)
      bs = bs4.BeautifulSoup(res.text, "html.parser")
      # bs1放的是标题和网址bs2放的是图片地址
      bs1 = bs.find_all('a', class_="xm-album-title ellipsis-2")
      bs2 = bs.find_all('a', class_="xm-album-cover")
      # 图片
      ls = []
      for i in range(len(bs1)):
            d = dict.fromkeys(("title", "albumId", "src", 'count'))
            d['title'] = bs1['title']# 标题
            d['albumId'] = bs1['href'].split('/')[-2]# 网址的albumId
            d['src'] = "https:" + bs2.img['src']# 图片
            d['count'] = bs2.find('div', class_='listen-count').span.text# 播放量
            ls.append(d)

      return ls

    # 访问目标专辑的网页,然后获取所有的章节的列表字典数据+"p1/"
    def get_album(self, albumId):
      res = requests.get(f"{self.url}/revision/album/v1/getTracksList?albumId={albumId}&pageNum=1&sort=0&pageSize=30",
                           headers=self.headers)
      js = json.loads(res.text)
      # 获取总页数 分页计算总页数算法
      pageSize = 1000
      totalRecord = int(js['data']['trackTotalCount'])
      totalPageNum = int((totalRecord + pageSize - 1) / pageSize)
      ls = []
      for i in range(totalPageNum):
            res = requests.get(
                f"{self.url}/revision/album/v1/getTracksList?albumId={albumId}&pageNum={i + 1}&sort=0&pageSize={pageSize}",
                headers=self.headers)
            js1 = json.loads(res.text)
            js1 = js1['data']['tracks']
            for item in js1:
                d = dict.fromkeys(('title', 'trackId', 'playCount'))
                d["title"] = item['title']# 标题
                d["playCount"] = item['playCount']# 播放量
                d["trackId"] = item['trackId']# 下载接口id
                ls.append(d)
      return ls

    # 下载音频文件,返回下载结果 需要提供章节字典 和目录名
    def donwn(self, section, sname):
      try:
            # 如果没有这个目录则创建一个目录
            if os.path.isdir(sname) == False:
                os.makedirs(sname)
            sname = sname + r"/"
            res = requests.get(f"https://www.ximalaya.com/revision/play/v1/audio?id={section['trackId']}&ptype=1",
                               headers=self.headers)
            js = json.loads(res.text)
            res = requests.get(js['data']['src'], headers=self.headers).content
            with open(sname + section['title'] + ".m4a", 'wb') as file:
                file.write(res)
            print(section['title'] + " 下载成功!")
      except:
            print(section['title'] + " 下载失败!")


    #将数据保存到excel表格中
    def to_excel(self, sections, sname):
      try:
            wb = openpyxl.Workbook()
            ws = wb.active# 获取工作表
            ws.freeze_panes = 'B2'
            #设置行宽 高width是字符数 height是像素
            ws.row_dimensions.height = 25
            ws.column_dimensions['A'].width = 50
            ws.column_dimensions['B'].width = 90
            ws.column_dimensions['C'].width = 20
            ws.append(['title', 'm4aUrl', 'playCount'])


            sname = sname + ".xlsx"
            for item in sections:
                res = requests.get(f"https://www.ximalaya.com/revision/play/v1/audio?id={item['trackId']}&ptype=1",
                                 headers=self.headers)
                js = json.loads(res.text)
                print(item['title'], js['data']['src'], item['playCount'])
                ws.append(, js['data']['src'], item['playCount']])
            wb.save(sname)
            print(f"保存到 {sname} 成功!")
      except:
            print(f"保存到 {sname} 失败!")


if __name__ == "__main__":
    while True:
      xmly = Ximalaya()
      while True:
            try:
                kw = input("请输入您想搜索的关键字:(书名或者作者)\r\n")
                ls = xmly.search(kw)
                for i, item in enumerate(ls):
                  txt = f"{i + 1}-{item['title']}-{item['count']}"
                  print(txt)
                xh = input(f"请输入您想要下载的专辑的序号:1-{len(ls)}返回上一步请输入'#'键\r\n")
                # 如果输入了#号键则继续循环问..不是则跳出循环
                if xh != '#':
                  try:
                        xh = int(xh) - 1
                        break
                  except:
                        print("输入有误!回到开始位置")

            except:
                print("关键字有误,或者没找到!")
      print("正在遍历所有的章节,这需要些时间.......")
      # 根据用户选的序号来选择遍历哪个有声书的所有章节
      sections = xmly.get_album(ls["albumId"])
      for i, item in enumerate(sections):
            print(i + 1, item['title'])
      ts = input(
            f"         有几种交互方式,请参考!\r\n1.请输入需要下载的章节序号:1-{len(sections)} 支持范围下载 例如输入:10-100\r\n2.如果您要全部都下载,请输入'#'键\r\n3.如果您要全部打印到excel表格里请输入'e'键\r\n4.退出按x键\r\n")
      name = ls["title"]
      if ts == "#":# 全部下载
            for item in sections:
                xmly.donwn(item, name)
      else:
            if '-' in ts:# 范围下载
                min, max = ts.split('-')
                for i in range(int(min), int(max) + 1):
                  xmly.donwn(sections, name)
            elif ts == 'e':# 将数据保存到excel表格里
                xmly.to_excel(sections, name)
            elif ts=='x':
                break
            else:# 按序号下载
                xmly.donwn(sections, name)
      ts=input("还要继续输入'j'键,退出输入任意键")
      if ts!='j':
            break




我自己在head这儿添加cookeis,好像没效果,还是我的cookie方式错语,求指导。谢谢!

miku520 发表于 2020-8-27 22:45:31

应该是格式问题吧
self.headers = {
            "user-agent" : "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36",
            "cookie" : "你的cookie",

}

疾风怪盗 发表于 2020-8-28 00:17:57

虽然无法解答楼主的问题,但是很感谢楼主分享了源码。。。。。。。。拿这个试了下,没用VIPcookie,就下载免费的音频,碰到一个问题,创建文件的时候,会有失败,原因在sname中有‘|’,无法创建文件夹和文件,名称不规范,所以失败了,可以改进下把这个split切割了,现在能下载成功了
# 下载音频文件,返回下载结果 需要提供章节字典 和目录名
    def donwn(self, section, sname):
      
      sname = sname.split('|')
      try:
            # 如果没有这个目录则创建一个目录
            if os.path.isdir(sname) == False:
                os.makedirs(sname)#文件名有不符合创建标准的就会失败
            sname = sname + r"/"
            res = requests.get(f"https://www.ximalaya.com/revision/play/v1/audio?id={section['trackId']}&ptype=1",
                               headers=self.headers)
            #print(res)
            js = json.loads(res.text)
            res = requests.get(js['data']['src'], headers=self.headers).content
            with open(sname + section['title'].split('|') + ".m4a", 'wb') as file:
                file.write(res)
            print(section['title'] + " 下载成功!")
      except:
            print(section['title'] + " 下载失败!")

疾风怪盗 发表于 2020-8-28 00:21:08

这是吾爱破解上的一段源码,发帖人说改下cookie就能下载VIP,楼主可以参考下
import requests
from lxml import etree
import os
import time
import json


def Get_ID_Name(url, headers):
    Contents_IDS = []
    r = requests.get(url, headers=headers)
    print(r)
    r.encoding = r.apparent_encoding
    html = etree.HTML(r.text)
    Titles = html.xpath('//div[@class="sound-list _Qp"]/ul/li/div/a/@title')
    Contents_lists = html.xpath('//div[@class="sound-list _Qp"]/ul/li/div/a/@href')
    for Contents_list in Contents_lists:
      links_Cache = str(Contents_list).split('/')[-1]
      JsonURL = 'https://www.ximalaya.com/revision/play/v1/audio?id={}&ptype=1'.format(links_Cache)
      Contents_IDS.append(JsonURL)
    return Titles, Contents_IDS


def Json_Get_links(Contents_IDS, headers):
    Itemlists = []
    n = 0
    for Contents_ID in Contents_IDS:
      contents = {}
      time.sleep(1.5)
      r1 = requests.get(Contents_ID, headers=headers)
      r1.encoding = r1.apparent_encoding
      results = json.loads(r1.text)
      id = results['data']['trackId']
      m4alinks = results['data']['src']
      contents['ID'] = id
      contents['M4aLinks'] = m4alinks
      Itemlists.append(contents)
      n += 1
      print('已采集{}个链接!'.format(n))
    # print(Itemlists)
    return Itemlists


def DownLoadM4A(Itemlists, filename):
    headers = {
      'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3775.400 QQBrowser/10.6.4208.400',
      # 'If-None-Match': '"llN9ISnSdOkEmb835lC9NQ_j47Kl"',
      # 'Host': 'fdfs.xmcdn.com',
    }
    if not os.path.exists('./XMLYFM'):
      os.mkdir('./XMLYFM')
    count = 0
    for filename1, Itemlist in zip(filename, Itemlists):
      srclinks = Itemlist['M4aLinks']
      print(srclinks)
      r2 = requests.get(srclinks, headers=headers)
      print(r2)
      # print(r2.raise_for_status())
      with open('./XMLYFM/' + str(filename1) + '.m4a', 'wb')as f:
            f.write(r2.content)
            count += 1
            print('已下载{}个音频文件!'.format(count))
    print("{}个音频文件已全部下载完成!".format(count))


if __name__ == '__main__':
    print('正在加载...')
    url = 'https://www.ximalaya.com/gerenchengzhang/29391994/'#更换URL下载页面内所有链接
    headers = {
      'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3775.400 QQBrowser/10.6.4208.400',
      'Cookie': '_xmLog=xm_kecz048az1wpks; s&e=8dc4e1b92c46d738b6942a843f86a855; x_xmly_traffic=utm_source%253A%2526utm_medium%253A%2526utm_campaign%253A%2526utm_content%253A%2526utm_term%253A%2526utm_from%253A; Hm_lvt_4a7d8ec50cfd6af753c4f8aee3425070=1598542624; Hm_lpvt_4a7d8ec50cfd6af753c4f8aee3425070=1598543278; s&a=B%0F%08W%0BR%1DZL%0C[Y%0AXL[%1CQVWX%02CWM%01WY%0F[NVV%5CCRBT@OK^XYBXLS',
      # 'Referer': 'https://www.ximalaya.com/gerenchengzhang/29391994/',
      # 'Host': 'www.ximalaya.com'
    }
    data1 = Get_ID_Name(url, headers)
    IDlinks = data1
    fileName = data1
    DownLoadM4A(Json_Get_links(IDlinks, headers), fileName)

ChinaLee 发表于 2020-8-28 15:41:58

疾风怪盗 发表于 2020-8-28 00:21
这是吾爱破解上的一段源码,发帖人说改下cookie就能下载VIP,楼主可以参考下

下载时暂时还会出错,我等会有空在研究。

ChinaLee 发表于 2020-8-28 15:47:06

miku520 发表于 2020-8-27 22:45
应该是格式问题吧
self.headers = {
            "user-agent" : "Mozilla/5.0 (Windows NT 10.0; WOW64) ...

按照你的方法添加cookies进去,下载vip音频还是失败的,不知道是不是我添加的喜马拉雅cookies方式不对,不知道喜马拉雅的cookies是要全部添加进去还是只要添加1&_token=后面的。

liuzhengyuan 发表于 2020-8-28 19:44:34

ChinaLee 发表于 2020-8-28 15:47
按照你的方法添加cookies进去,下载vip音频还是失败的,不知道是不是我添加的喜马拉雅cookies方式不对, ...

也有可能是楼上的 cookie 失效了

ChinaLee 发表于 2020-8-28 19:49:28

liuzhengyuan 发表于 2020-8-28 19:44
也有可能是楼上的 cookie 失效了

自己的cookie,刚捉的,网站还登陆着,不知道是不是cookie填写的方式不对,是只要填1&_token=后面的还是全部都要,三种都试了好像还是不行。不知道怎么回事。

liuzhengyuan 发表于 2020-8-28 19:53:59

ChinaLee 发表于 2020-8-28 19:49
自己的cookie,刚捉的,网站还登陆着,不知道是不是cookie填写的方式不对,是只要填1&_token=后面的还是全 ...

全都要,cookie 放 headers 里
页: [1]
查看完整版本: 这个喜马拉雅的cookies要插在那个位置