乐趣区

爬取音乐资源

一直苦于找不到好的音乐资源,网传 python 爬虫异常强大,刚好有点 python 基础就想着做一个脚本爬一点 mp3 资源,废话不多说,先看看效果吧。

/home/roland/PycharmProjects/Main.py
please input the artist name: billie eilish

Process finished with exit code 0

运行之后需要输入爬取的歌手名,这里我们填写一个喜欢的歌手名然后回车即可(支持中文歌手),日志并没有输出内容,而是直接将 mp3 文件保存到 save_path 路径下,如下图所示:

这里用的 python 版本是 3.6 理论上 3.X 版本都可以直接运行,不用额外装 request 库。
代码分析

  • 下面函数的作用是拼接请求报头,请求方式为POST
  • 获取方式:打开浏览器控制台 —->NetWork 选项 —> 发送一次请求 —> 查看 POST

以 chrome 为例
按下 F12 打开控制台
依次依照下图找到 Form Data 即为所需,当然,并不是所有的请求方式都会用到 data 报头,我们这么做的目的是模仿浏览器访问网页的过程。

而后把需要添加到报头的字段依次添加进来,这里 pagescontent是动态变量(原网址为 ajax 异步加载)content即为查找的歌手

def resemble_data(content, index):
    data = {}
    data['types'] = 'search'
    data['count'] = '30'
    data['source'] = 'netease'
    data['pages'] = index
    data['name'] = content
    data = urllib.parse.urlencode(data).encode('utf-8')
    return data

此外我们还需要获取到 User-Agent 对应的代码是:

opener.addheaders =
 [('User-Agent','Mozilla/5.0 (X11; Linux x86_64) 
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36')]

这个东西在那里获取呢?

我们直接从浏览器的控制台获取就好了,目的将 python 的 request 请求伪装成浏览器访问。

    # set proxy agent
    proxy_support = urllib.request.ProxyHandler({'http:': '119.6.144.73:81'})
    opener = urllib.request.build_opener(proxy_support)
    urllib.request.install_opener(opener)
    # set proxy agent

这里我们又设置了一个代理 ip,防止服务器的反爬虫机制(一个 ip 频繁访问会被认为是爬虫而不是访客操作,这里仅仅是实例,我们可以爬取代理 ip 的地址和端口号来让更多 ip 同时访问,减小被认定为爬虫的可能)
下面是爬取代理 ip 的例子(不感兴趣的话可以直接跳过)

import urllib.request
import urllib.parse
import re
url = 'http://31f.cn/'
head = {}
head['User-Agent'] = 
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36
 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36'
response = urllib.request.urlopen(url)
html_document = response.read().decode('utf-8')
pattern_ip = re.compile(r'<td>(\d+\.\d+\.\d+\.\d+)</td>[\s\S]*?
<td>(\d{2,4})</td>')
ip_list = pattern_ip.findall(html_document)
print(len(ip_list))
for item in ip_list:
    print("ip 地址是:%s 端口号是:%s" % (item[0], item[1]))


这里的 response 返回的其实是一个音乐文件的链接地址,格式类似于 xxxxuuid.mp3 我们把默认的 uuid.mp3 直接命名为歌曲名.mp3,然后以二进制文件格式写入文件。

 data = {}
    data['types'] = 'url'
    data['id'] = id
    data['source'] = 'netease'
    data = urllib.parse.urlencode(data).encode('utf-8')
    response = urllib.request.urlopen(url, data)
    music_url_str = response.read().decode('utf-8')
    music_url = pattern.findall(music_url_str)
    result = urllib.request.urlopen(music_url[0])
    file = open(save_path+name+'.mp3', 'wb')
    file.write(result.read())

至于Request url,可以在这里获取(当然,这只是一个例子,这个 url 并不是例子所用的 url):

以下是完整的代码,把音乐文件的保存路径 save_path = '/home/roland/Spider/Img/ 修改成自己的保存路径就可以了

import urllib.request
import urllib.parse
import json
import re


def resemble_data(content, index):
    data = {}
    data['types'] = 'search'
    data['count'] = '30'
    data['source'] = 'netease'
    data['pages'] = index
    data['name'] = content
    data = urllib.parse.urlencode(data).encode('utf-8')
    return data


def request_music(url, content):
    # set proxy agent
    proxy_support = urllib.request.ProxyHandler({'http:': '119.6.144.73:81'})
    opener = urllib.request.build_opener(proxy_support)
    opener.addheaders = [('User-Agent','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36')]
    urllib.request.install_opener(opener)
    # set proxy agent
    total = []
    pattern = re.compile(r'\(([\s\S]*)\)')
    for i in range(1, 10):
        data = resemble_data(content, str(i))
        response = urllib.request.urlopen(url, data)
        result = response.read().decode('unicode_escape')
        json_result = pattern.findall(result)
        total.append(json_result)
    return total


def save_music_file(id, name):
    save_path = '/home/roland/Spider/Img/'
    pattern = re.compile('http.*?mp3')
    url = 'http://www.gequdaquan.net/gqss/api.php?callback=jQuery111307210973120745481_1533280033798'
    data = {}
    data['types'] = 'url'
    data['id'] = id
    data['source'] = 'netease'
    data = urllib.parse.urlencode(data).encode('utf-8')
    response = urllib.request.urlopen(url, data)
    music_url_str = response.read().decode('utf-8')
    music_url = pattern.findall(music_url_str)
    result = urllib.request.urlopen(music_url[0])
    file = open(save_path+name+'.mp3', 'wb')
    file.write(result.read())
    file.flush()
    file.close()


def main():
    url = 'http://www.gequdaquan.net/gqss/api.php?callback=jQuery11130967955054499249_1533275477385'
    content = input('please input the artist name:')
    result = request_music(url, content)
    for group in result[0]:
        target = json.loads(group)
        for item in target:
            save_music_file(str(item['id']), str(item['name']))


main()
退出移动版