【爬虫新手必看】歌曲网站爬虫案例详解
本帖最后由 taoyuanhang 于 2023-9-3 07:58 编辑项目链接:https://www.gequbao.com/
动机:大部分的音乐需要VIP才可以听,并且下载也要VIP。
所以,我想找一个不用VIP就可以听歌的音乐站,这不,就让我找到了?
最近见到什么网站都想爬一爬,所以想先拿这个网站练练手
由于我是一边分析一边写的,所以文章会长一点,新手可以慢慢看,代码写完会放在下面的,不要着急~
首先这个网站是长这样的:
https://xxx.ilovefishc.com/forum/202308/28/120856vyt14cljr83evzrv.png.thumb.jpg
然后我随便点击了一首歌曲,它的页面是这样的,没有在新标签页打开,并且刷新了,如图
https://xxx.ilovefishc.com/forum/202308/28/121030hli15kzeutzu9ec6.png.thumb.jpg
所以我猜这个用的不是Ajax接口,而是由服务器渲染再返回客户端的
点击f12,刷新,我猜的果然没错
https://xxx.ilovefishc.com/forum/202308/28/121412uo79mcm33p0onmzo.png.thumb.jpg
这种的话我比较喜欢用正则表达式,到时候不行再用xpath,因为正则表达式比较简单。(我的意思是我个人比较喜欢,并不是说xpath不好)
好的,我们这个主要是下载歌曲,并不是获取它的歌名、歌手等,咱们主要的目的不是自动下载吗?
https://xxx.ilovefishc.com/forum/202308/28/122325h41yo4i17a4c1c8k.png.thumb.jpg
这里的下载并不是直接下载了,而是访问歌曲的主页,那我们就去主页看看
这里的歌词和歌曲是分开的(像极了B站的音视频分开)
https://xxx.ilovefishc.com/forum/202308/28/122639j7hvn5l7c975duzn.png.thumb.jpg
这边审查元素发现下载链接已经很明显了
https://xxx.ilovefishc.com/forum/202308/28/122800ckxlxs4lzi1vvxlx.png.thumb.jpg
我们尝试直接访问链接,好家伙,这还不是真正的下载,而是在新标签页打开歌曲,没事,这个requests可以解决的
https://xxx.ilovefishc.com/forum/202308/28/122934o8uvvmz1gi82gv88.png.thumb.jpg
等一下,突然发现这个是酷我音乐的外链。。。
没事没事,反正外链在手,可以下载就行
开始编写代码啦!
首先步骤很清晰了
爬取关键词搜索部分->由用户选择歌曲->访问主页获取音乐链接直接下载
这次就不做UI了,快开学了,先做一个命令行版本
首先用户输入,直接搜索,得到网页源码进行匹配
https://xxx.ilovefishc.com/forum/202308/28/124456fkqw3c9p1ccckmcz.png.thumb.jpg
可以爬到!我们直接上正则表达式吧!
可以,整个页面都直接爬下来了,返回一个列表,里面的元素都是元组,元组第一个是相对链接,第二个歌名,第三个是歌手
那我们美化一下输出
https://xxx.ilovefishc.com/forum/202308/28/133628kkahkrdidxsiadou.png.thumb.jpg
看着还行,接下来就是歌曲链接获取了
这个很简单,也是正则表达式搞定,歌曲链接在这个位置
https://xxx.ilovefishc.com/forum/202308/28/140715y22ljgmgj2n8hhbl.png.thumb.jpg
所以说,正则表达式应该是这个样子:
const url = '(.*?)'.replace好的,歌曲下载就是直接get这个直链,直接以wb打开mp3,再写入response.content就可以了
完整代码如下:
import requests
import re
def get_music_list(kwd):
response=requests.get("https://www.gequbao.com/s/"+kwd)
pattern=re.compile('''<div class="col-5 col-content">
<a href="(.*?)"
class="text-primary font-weight-bold"
target="_blank">(.*?)
</a>
</div>
<div class="text-success col-4 col-content">
(.*?)
</div>''')
result=re.findall(pattern,response.text)
return result
def print_music(music_list):
msc_num=1
for item in music_list:
#print(" {:<15}{:<20}{:<10} ".format(*item))
print(str(msc_num)+". {:<15}{:<30}{:<10} ".format(*item))
msc_num+=1
def get_download_url(url):
url='https://www.gequbao.com/'+url
response=requests.get(url)
pattern=re.compile("""const url = '(.*?)'.replace""")
result=re.findall(pattern,response.text)
return result
def main():
result=get_music_list(input("请输入歌手/歌曲名称:"))
print_music(result)
try:
while True:
music_num=int(input("请选择歌曲(序号):"))
music=result
print("已选定:https://www.gequbao.com/"+music)
if input("你可以先试听,也可以直接下载,继续吗?(y/n)")=="y":
break
print("已选择:重新输入")
except:
print("输入不合法,请重新运行")
return
music=requests.get(get_download_url(music))
music_data=music.content
with open(f"{result}.mp3","wb") as f:
f.write(music_data)
print("下载完成!")
main()
运行结果如下:
https://xxx.ilovefishc.com/forum/202308/28/141159zoyvji55zzvjj4yo.png.thumb.jpg
非常完美!
以上就是这个帖子的所有内容了,喜欢的话可以评个分支持一下吗?你的支持就是我坚持创作的动力! ============== RESTART: C:/Users/Administrator/Documents/gq001.py ==============
Traceback (most recent call last):
File "C:/Users/Administrator/Documents/gq001.py", line 1, in <module>
import requests
ModuleNotFoundError: No module named 'requests' gzl5755 发表于 2023-9-3 09:59
您好!这个方法可以下载网抑云音乐吗
with open(f"{input('歌名:')}.mp3",'wb') as i:
i.write(__import__('requests').get(f"http://music.163.com/song/media/outer/url?id={input('请输入网址:')}.mp3").content)
看上去挺有意思的。等有空时试试。 您好!这个方法可以下载网抑云音乐吗{:1_926:} 感谢分享 厉害,还得先分析才能写代码 好好学习 我也去爬一爬。 pip install requests
要安装一下模块