爬虫基础之爬取歌曲宝歌曲批量下载
声明:本案列仅供学习交流使用 任何用于非法用途均与本作者无关
需求分析:
- 网站:邓紫棋-mp3在线免费下载-歌曲宝-找歌就用歌曲宝-MP3音乐高品质在线免费下载 (gequbao.com)
- 爬取 歌曲名 歌曲 实现歌手名称下载所有歌曲
requests (发送HTTP请求) | re(用于正则表达式匹配和处理) |
parsel (解析HTML或XML文档) | os (用于与操作系统进行交互,如文件和目录操作) |
监听数据包:
- 打开开发者工具 F12 or 右击点击检查 点击网络
- 点击下一页 或者往下滑
- Ctrl+F 快捷键打开搜索框 输入想要爬取的数据
分析:
通过此界面拿到所有歌曲的内页
然后点进去分析详情页的数据
点击播放按钮 监听数据包 复制下图的URL 地址到浏览器中打开
发现就会下载这个音乐文件
接着点击下载歌曲里面的下载高品质MP3
找到这个请求的数据包 后续发送请求 通过正则可以将下载链接提取出来
好的 分析完毕 我们开始写代码
老样子 右击复制 cURL(bash) 打开我们的爬虫工具
爬虫工具库-spidertools.cn
复制代码到本地Py文件
以下是实现一首歌曲的采集
发现是根据每首歌的id 来下载的歌曲 因此我们需要拿到所有下载歌曲的id
在每首歌曲的详情页
# 导包
import re
import requests
headers = {
"accept": "application/json, text/javascript, */*; q=0.01",
"accept-language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6",
"content-type": "application/x-www-form-urlencoded; charset=UTF-8",
"origin": "https://www.gequbao.com",
"priority": "u=1, i",
"referer": "https://www.gequbao.com/music/9653",
"sec-ch-ua": "\"Chromium\";v=\"128\", \"Not;A=Brand\";v=\"24\", \"Microsoft Edge\";v=\"128\"",
"sec-ch-ua-mobile": "?0",
"sec-ch-ua-platform": "\"Windows\"",
"sec-fetch-dest": "empty",
"sec-fetch-mode": "cors",
"sec-fetch-site": "same-origin",
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36 Edg/128.0.0.0",
"x-requested-with": "XMLHttpRequest"
}
cookies = {
"Hm_lvt_c2b69091f94cb4368f25c28fc7c2d28c": "1736209777,1736210463",
"HMACCOUNT": "0EB52C16E9A34AE0",
"Hm_lpvt_c2b69091f94cb4368f25c28fc7c2d28c": "1736210603"
}
url = "https://www.gequbao.com/api/play-url"
data = {
"id": "SF9bVDxXUl1RQ1heUHJe"
}
response = requests.post(url, headers=headers, cookies=cookies, data=data)
# 通过re正则提取 下载的url地址
down_url = ''.join(re.findall(r'"url":"(.*?)"',response.text)[0]).replace('\\','')
# 保存数据 歌曲 图片 视频 保存均为二进制的格式
content = requests.get(url=down_url, headers=headers, cookies=cookies, data=data).content
# 以二进制的形式 进行写入保存
with open('1.mp3','wb') as f:
f.write(content)
接着我们拿到所有歌曲的内页链接 里面包含歌曲的id
# 发送请求
first_url = 'https://www.gequbao.com/s/%E9%82%93%E7%B4%AB%E6%A3%8B'
# 后面的参数 其实就是邓紫棋
result= requests.get(url=first_url,headers=headers,cookies=cookies,data=data)
print(result.text)
从返回的数据中搜索是否存在我们想要的数据
提取数据 打开元素面板 查看元素所在的位置
select = parsel.Selector(result.text)
lis = select.css('.row .col-8.col-content')
for li in lis:
in_id = li.css('a::attr(href)').get().split('/')[-1]
接着我们构造URL 对详情页发送请求
url = f'https://www.gequbao.com/music/{in_id}'
从返回的数据中通过正则提取我们想要的数据 id
resp = requests.get(url, headers=headers)
# print(resp.text)
# 歌曲id
play_id = re.findall(r"window.play_id = '(.*?)';", resp.text)[0]
# 歌曲名字
play_title = re.findall(r"window.mp3_title = '(.*?)';", resp.text)[0]
# 歌手
play_author = re.findall(r"window.mp3_author = '(.*?)';", resp.text)[0]
# 因为正则提取出来的是列表 对列表进行取值
最后 还记得开始下载一首歌曲的请求嘛 对此发送请求
将我们从每首歌的详情页获取到的play_id 传进去
完整的代码如下
import requests
import re
import parsel
import os
inp = input('请输入要采集的歌手:')
headers = {
'user-agent':
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36 Edg/130.0.0.0'
}
first_url = f'https://www.gequbao.com/s/{inp}'
# .row .col-8.col-content a
result = requests.get(url=first_url,headers=headers)
select = parsel.Selector(result.text)
lis = select.css('.row .col-8.col-content')
for li in lis:
in_id = li.css('a::attr(href)').get().split('/')[-1]
# print(in_id)
# 以上代码拿到id
# 构建详情页链接
url = f'https://www.gequbao.com/music/{in_id}'
resp = requests.get(url, headers=headers)
# print(resp.text)
play_id = re.findall(r"window.play_id = '(.*?)';", resp.text)[0]
play_title = re.findall(r"window.mp3_title = '(.*?)';", resp.text)[0]
play_author = re.findall(r"window.mp3_author = '(.*?)';", resp.text)[0]
# print(play_id,play_title,play_author)
# 下载歌曲的链接 需要传入每个歌曲的id
link = 'https://www.gequbao.com/api/play-url'
data = {
'id': play_id
}
response = requests.post(url=link, data=data, headers=headers)
json_data = response.json()
# 获取json数据
# 提取下载链接
play_url = json_data['data']['url']
最后我们根据不同歌手来保存数据
需要导入os 模块
# 获取二进制数据
content = requests.get(play_url, headers=headers).content
# 定义文件目录
filed_name=f'music\\{play_author}\\'
# 自动创建 文件夹
if not os.path.exists(filed_name):
os.makedirs(filed_name)
# 以二进制的数据写入保存
with open(f'{filed_name}' + play_author + play_title + '.mp3', 'wb') as f:
f.write(content)
print(f'正在采集{play_author}{play_title}歌曲')
以下是本次案例的所有代码 仅供学习参考使用
import requests
import re
import parsel
import os
inp = input('请输入要采集的歌手:')
headers = {
'user-agent':
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36 Edg/130.0.0.0'
}
first_url = f'https://www.gequbao.com/s/{inp}'
# .row .col-8.col-content a
result = requests.get(url=first_url,headers=headers)
select = parsel.Selector(result.text)
lis = select.css('.row .col-8.col-content')
for li in lis:
in_id = li.css('a::attr(href)').get().split('/')[-1]
# print(in_id)
# 以上代码拿到id
url = f'https://www.gequbao.com/music/{in_id}'
resp = requests.get(url, headers=headers)
# print(resp.text)
play_id = re.findall(r"window.play_id = '(.*?)';", resp.text)[0]
play_title = re.findall(r"window.mp3_title = '(.*?)';", resp.text)[0]
play_author = re.findall(r"window.mp3_author = '(.*?)';", resp.text)[0]
# print(play_id,play_title,play_author)
link = 'https://www.gequbao.com/api/play-url'
data = {
'id': play_id
}
response = requests.post(url=link, data=data, headers=headers)
json_data = response.json()
play_url = json_data['data']['url']
content = requests.get(play_url, headers=headers).content
filed_name=f'music\\{play_author}\\'
if not os.path.exists(filed_name):
os.makedirs(filed_name)
with open(f'{filed_name}' + play_author + play_title + '.mp3', 'wb') as f:
f.write(content)
print(f'正在采集{play_author}{play_title}歌曲')
运行代码
本次的案例分享就到此结束啦 感谢大家的观看 您的点赞和关注是我更新的动力