在multiprocessing.dummy线程池,基于线程 pool.map(callback,alist)再次处理数据:爬取某音乐网站热歌排行榜里面的歌曲!

本作品不可用于任何商业途径,仅供学习交流!!!

分析:

在某音乐网站热歌排行榜里面,随便点击一首歌曲,进入歌曲网页,打开浏览器的开发者工具,刷新网页,播放下歌曲,浏览器的抓包工具network抓包如下图:

在某音乐网站热歌排行榜网页里面,打开浏览器的开发者工具,刷新网页,浏览器的抓包工具network抓包如下图:

代码部分:

线程池:

from multiprocessing.dummy import Pool

pool.map(callback,alist) ---- 可以使用callback(回调函数)对alist中的每一个元素进行指定形式(回调函数)的异步操作!

抓取到网站排行榜里面歌曲的id和name

import os
import requests,time
from multiprocessing.dummy import Pool#需要用到的包


dirName = 'musickw'
if not os.path.exists(dirName):
    os.mkdir(dirName)#设置保存下载歌曲的文件夹

headers = {
    'csrf': 'BMULNZWEZ3B',
    'Cookie': 'kw_token=BMULNZWEZ3B',
    'Referer': 'http://www.kuwo.cn/rankList',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.67 Safari/537.36 Edg/87.0.664.52',
}#伪装成浏览器,要是headers设置上面这些还报错,再加其他的进去

music_list = []#抓取排行榜前4页歌曲的id,name放在这个music_list列表里面
for page in range(1,4):#抓取排行榜前4页歌曲的id,name

    params = {
        'bangId': '93',
        'pn': str(page),
        'rn': '30',
        'httpsStatus': '1',
        'reqId': '04ae7fd0-79d2-11eb-97b6-f59160d5f14c',
    }

    session = requests.Session()#requests中sessiondcookie自动处理
    id_url = '获取排行榜歌曲id和歌曲name的ajax请求url'
    response_dic = session.get(url=id_url,headers=headers,params=params).json()
    time.sleep(0.5)#设置个等待时间,避免网站检查到请求频繁被禁出错
    reqId = response_dic['reqId']

    for i in response_dic['data']['musicList']:
        music_id = i['rid']
        music_name = i['name']
        info_dic = {
            'id':music_id,
            'name':music_name,
            'reqId':reqId,
        }
        music_list.append(info_dic)#上面是数据定位提取,放在个字典里面,然后把歌曲的id、name以字典的形式放在music_list列表里面

第一个 pool.map(callback,alist) 获取到歌曲的播放地址:

import os
import requests,time
from multiprocessing.dummy import Pool#需要用到的包


dirName = 'musickw'
if not os.path.exists(dirName):
    os.mkdir(dirName)#设置保存下载歌曲的文件夹

headers = {
    'csrf': 'BMULNZWEZ3B',
    'Cookie': 'kw_token=BMULNZWEZ3B',
    'Referer': 'http://www.kuwo.cn/rankList',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.67 Safari/537.36 Edg/87.0.664.52',
}#伪装成浏览器,要是headers设置上面这些还报错,再加其他的进去

music_list = []#抓取排行榜前4页歌曲的id,name放在这个music_list列表里面
for page in range(1,4):#抓取排行榜前4页歌曲的id,name

    params = {
        'bangId': '93',
        'pn': str(page),
        'rn': '30',
        'httpsStatus': '1',
        'reqId': '04ae7fd0-79d2-11eb-97b6-f59160d5f14c',
    }

    session = requests.Session()#requests中sessiondcookie自动处理
    id_url = '获取排行榜歌曲id和歌曲name的ajax请求url'
    response_dic = session.get(url=id_url,headers=headers,params=params).json()
    time.sleep(0.5)#设置个等待时间,避免网站检查到请求频繁被禁出错
    reqId = response_dic['reqId']

    for i in response_dic['data']['musicList']:
        music_id = i['rid']
        music_name = i['name']
        info_dic = {
            'id':music_id,
            'name':music_name,
            'reqId':reqId,
        }
        music_list.append(info_dic)#上面是数据定位提取,放在个字典里面,然后把歌曲的id、name以字典的形式放在music_list列表里面

def get_musicUrl(music_list):

    headers = {
        'csrf': 'BMULNZWEZ3B',
        'Cookie': 'kw_token=BMULNZWEZ3B',
        'Referer': 'http://www.kuwo.cn/rankList',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.67 Safari/537.36 Edg/87.0.664.52',
    }

    reqId = music_list['reqId']
    music_id = music_list['id']
    music_name = music_list['name']#把music_list列表里面字典,字典里面的歌曲id、name、reqId提取出来,作为下面params的参数

    params = {
        'format': 'mp3',
        'rid': music_id,
        'response': 'url',
        'type': 'convert_url3',
        'br': '128kmp3',
        'from': 'web',
        't': str(int(round(time.time() * 1000))),#当前的时间戳
        'httpsStatus': '1',
        'reqId': reqId,
    }
    music_url = '获取到歌曲播放地址的ajax请求url'
    try:
        response_music_url = session.get(url=music_url, headers=headers, params=params).json()['url']
        time.sleep(1)#设置个等待时间,避免网站检查到请求频繁被禁出错
        info_dic =  {
            'url':response_music_url,
            'name':music_name,
        }
        return info_dic #把获取到的歌曲播放地址和name封装到字典里面作为回调函数的返回值
    except:#处理异常报错
        response_music_url = session.get(url=music_url, headers=headers, params=params).json()['url']
        info_dic = {
            'url': response_music_url,
            'name': music_name,
        }
        return info_dic

if __name__ == '__main__':
    pool = Pool(10)
    music_url = pool.map(get_musicUrl,music_list)#返回的是歌曲的播放地址和name的字典
    pool.close()
    pool.join()

第二个 pool.map(callback,alist) 对获取到的歌曲播放地址发起请求:

import os
import requests,time
from multiprocessing.dummy import Pool#需要用到的包


dirName = 'musickw'
if not os.path.exists(dirName):
    os.mkdir(dirName)#设置保存下载歌曲的文件夹

headers = {
    'csrf': 'BMULNZWEZ3B',
    'Cookie': 'kw_token=BMULNZWEZ3B',
    'Referer': 'http://www.kuwo.cn/rankList',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.67 Safari/537.36 Edg/87.0.664.52',
}#伪装成浏览器,要是headers设置上面这些还报错,再加其他的进去

music_list = []#抓取排行榜前4页歌曲的id,name放在这个music_list列表里面
for page in range(1,4):#抓取排行榜前4页歌曲的id,name

    params = {
        'bangId': '93',
        'pn': str(page),
        'rn': '30',
        'httpsStatus': '1',
        'reqId': '04ae7fd0-79d2-11eb-97b6-f59160d5f14c',
    }

    session = requests.Session()#requests中sessiondcookie自动处理
    id_url = '获取排行榜歌曲id和歌曲name的ajax请求url'
    response_dic = session.get(url=id_url,headers=headers,params=params).json()
    time.sleep(0.5)#设置个等待时间,避免网站检查到请求频繁被禁出错
    reqId = response_dic['reqId']

    for i in response_dic['data']['musicList']:
        music_id = i['rid']
        music_name = i['name']
        info_dic = {
            'id':music_id,
            'name':music_name,
            'reqId':reqId,
        }
        music_list.append(info_dic)#上面是数据定位提取,放在个字典里面,然后把歌曲的id、name以字典的形式放在music_list列表里面

def get_musicUrl(music_list):

    headers = {
        'csrf': 'BMULNZWEZ3B',
        'Cookie': 'kw_token=BMULNZWEZ3B',
        'Referer': 'http://www.kuwo.cn/rankList',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.67 Safari/537.36 Edg/87.0.664.52',
    }

    reqId = music_list['reqId']
    music_id = music_list['id']
    music_name = music_list['name']#把music_list列表里面字典,字典里面的歌曲id、name、reqId提取出来,作为下面params的参数

    params = {
        'format': 'mp3',
        'rid': music_id,
        'response': 'url',
        'type': 'convert_url3',
        'br': '128kmp3',
        'from': 'web',
        't': str(int(round(time.time() * 1000))),#当前的时间戳
        'httpsStatus': '1',
        'reqId': reqId,
    }
    music_url = '获取到歌曲播放地址的ajax请求url'
    try:
        response_music_url = session.get(url=music_url, headers=headers, params=params).json()['url']
        time.sleep(1)#设置个等待时间,避免网站检查到请求频繁被禁出错
        info_dic =  {
            'url':response_music_url,
            'name':music_name,
        }
        return info_dic #把获取到的歌曲播放地址和name封装到字典里面作为回调函数的返回值
    except:#处理异常报错
        response_music_url = session.get(url=music_url, headers=headers, params=params).json()['url']
        info_dic = {
            'url': response_music_url,
            'name': music_name,
        }
        return info_dic

def get_music_content(url_dic):对获取到的歌曲播放地址发起请求
    headers = {
        'csrf': 'BMULNZWEZ3B',
        'Cookie': 'kw_token=BMULNZWEZ3B',
        'Referer': 'http://www.kuwo.cn/rankList',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.67 Safari/537.36 Edg/87.0.664.52',
    }
    url = url_dic['url']
    name = url_dic['name']  #字典里面的歌曲播放地址 、name、提取出来
    # music_name = name +'.mp3'
    print(time.strftime("%y-%m-%d %H:%M:%S"),':正在下载music:{} ......'.format(name))
    music_data = session.get(url=url,headers=headers).content #对歌曲播放地址发起请求
    info_dic = {
        'content':music_data,
        'name':name,
    }
    return info_dic #把请求获取到的歌曲二进制数据和name封装到字典里面作为回调函数的返回值



if __name__ == '__main__':
    pool = Pool(10)
    music_url = pool.map(get_musicUrl,music_list)#返回的是歌曲的播放地址和name的字典
    music_content = pool.map(get_music_content,music_url)#返回的是歌曲的二进制数据和name的字典
    pool.close()
    pool.join()

第三个 pool.map(callback,alist) 对获取到的歌曲二进制数据和name持久化存储(全部代码):

import os
import requests,time
from multiprocessing.dummy import Pool#需要用到的包


dirName = 'musickw'
if not os.path.exists(dirName):
    os.mkdir(dirName)#设置保存下载歌曲的文件夹

headers = {
    'csrf': 'BMULNZWEZ3B',
    'Cookie': 'kw_token=BMULNZWEZ3B',
    'Referer': 'http://www.kuwo.cn/rankList',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.67 Safari/537.36 Edg/87.0.664.52',
}#伪装成浏览器,要是headers设置上面这些还报错,再加其他的进去

music_list = []#抓取排行榜前4页歌曲的id,name放在这个music_list列表里面
for page in range(1,4):#抓取排行榜前4页歌曲的id,name

    params = {
        'bangId': '93',
        'pn': str(page),
        'rn': '30',
        'httpsStatus': '1',
        'reqId': '04ae7fd0-79d2-11eb-97b6-f59160d5f14c',
    }

    session = requests.Session()#requests中sessiondcookie自动处理
    id_url = '获取排行榜歌曲id和歌曲name的ajax请求url'
    response_dic = session.get(url=id_url,headers=headers,params=params).json()
    time.sleep(0.5)#设置个等待时间,避免网站检查到请求频繁被禁出错
    reqId = response_dic['reqId']

    for i in response_dic['data']['musicList']:
        music_id = i['rid']
        music_name = i['name']
        info_dic = {
            'id':music_id,
            'name':music_name,
            'reqId':reqId,
        }
        music_list.append(info_dic)#上面是数据定位提取,放在个字典里面,然后把歌曲的id、name以字典的形式放在music_list列表里面

def get_musicUrl(music_list):

    headers = {
        'csrf': 'BMULNZWEZ3B',
        'Cookie': 'kw_token=BMULNZWEZ3B',
        'Referer': 'http://www.kuwo.cn/rankList',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.67 Safari/537.36 Edg/87.0.664.52',
    }

    reqId = music_list['reqId']
    music_id = music_list['id']
    music_name = music_list['name']#把music_list列表里面字典,字典里面的歌曲id、name、reqId提取出来,作为下面params的参数

    params = {
        'format': 'mp3',
        'rid': music_id,
        'response': 'url',
        'type': 'convert_url3',
        'br': '128kmp3',
        'from': 'web',
        't': str(int(round(time.time() * 1000))),#当前的时间戳
        'httpsStatus': '1',
        'reqId': reqId,
    }
    music_url = '获取到歌曲播放地址的ajax请求url'
    try:
        response_music_url = session.get(url=music_url, headers=headers, params=params).json()['url']
        time.sleep(1)#设置个等待时间,避免网站检查到请求频繁被禁出错
        info_dic =  {
            'url':response_music_url,
            'name':music_name,
        }
        return info_dic #把获取到的歌曲播放地址和name封装到字典里面作为回调函数的返回值
    except:#处理异常报错
        response_music_url = session.get(url=music_url, headers=headers, params=params).json()['url']
        info_dic = {
            'url': response_music_url,
            'name': music_name,
        }
        return info_dic

def get_music_content(url_dic):对获取到的歌曲播放地址发起请求
    headers = {
        'csrf': 'BMULNZWEZ3B',
        'Cookie': 'kw_token=BMULNZWEZ3B',
        'Referer': 'http://www.kuwo.cn/rankList',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.67 Safari/537.36 Edg/87.0.664.52',
    }
    url = url_dic['url']
    name = url_dic['name']  #字典里面的歌曲播放地址 、name、提取出来
    # music_name = name +'.mp3'
    print(time.strftime("%y-%m-%d %H:%M:%S"),':正在下载music:{} ......'.format(name))
    music_data = session.get(url=url,headers=headers).content #对歌曲播放地址发起请求
    info_dic = {
        'content':music_data,
        'name':name,
    }
    return info_dic #把请求获取到的歌曲二进制数据和name封装到字典里面作为回调函数的返回值

def get_music_mp3(content_dic):

    content = content_dic['content']
    name = content_dic['name'] #字典里面的歌曲播二进制数据 、name、提取出来
    music_name = name + '.mp3'#保存格式
    dirName = 'musickw'
    fileName = dirName + '/' + music_name
    with open(fileName,'wb') as fp:
        fp.write(content)
        print(time.strftime("%y-%m-%d %H:%M:%S"),': music: {} 下载成功 !!!'.format(name))

if __name__ == '__main__':
    pool = Pool(10)
    music_url = pool.map(get_musicUrl,music_list)#返回的是歌曲的播放地址和name的字典,把返回参数music_url 给下一个pool.map()作为里面的alist
    music_content = pool.map(get_music_content,music_url)#返回的是歌曲的二进制数据和name的字典
    pool.map(get_music_mp3,music_content)#最后一个pool.map()可以没有返回
    pool.close()#关闭线程池
    pool.join()

ok,这样就完成了! 下面是效果图:

本作品不可用于任何商业途径,仅供学习交流!!!

原文地址:https://www.cnblogs.com/YYQ-4414/p/14469903.html