Python音乐爬虫完美绕过反爬


Posted in Python onAugust 30, 2021

前言

大家好,我叫善念。

这是我的第二篇博客,也是第一篇技术博客,希望大家多多支持,让我更加有动力去更新一些python爬虫类的案例教程。

开始

确立目标网址:点击进入

Python音乐爬虫完美绕过反爬

进入到跳转页面:

Python音乐爬虫完美绕过反爬

可以看到出现了咱们需要的一些音乐

分析(x0)

这些音乐的源文件地址是否在咱们的网页元素中,然后再查看网页源代码中是否有咱们需要的内容。(注:网页元素与网页源代码不一定是一样的,网页元素是经过浏览器渲染后的源代码,而源代码纯粹就是服务器给咱们传送过来的原始数据)

网页元素中只有封面图片的资源,没用音频源文件地址:

Python音乐爬虫完美绕过反爬

网页源代码中同样没有咱们需要的内容:

Python音乐爬虫完美绕过反爬

分析(x1)

其实没有才正常(这种大型网站的数据不会让你这么轻易抓取)....不过是带大家走一遍流程,对别的网站也要这样分析

那么咱们开始播放音乐抓包,看是否能抓到数据:

Python音乐爬虫完美绕过反爬

果然是经过触发播放按钮后,服务器传给咱们客户端的。(ajax)

而咱们抓到的这个源文件地址

Python音乐爬虫完美绕过反爬

除了这两段外,其它的应该都是固定死的。

分析(x2)

那么我假设这两段是从我开始访问这首歌曲页面的时候生成的,比如后面那串数字为这首音乐在服务器数据库中的对应的一个ID值呢?

假设是合理的,不过由于咱们前面已经查看过源代码和网页元素中找不到这些值,我就不在这里浪费时间了。

分析(x3)

这里我和大家讲一下,咱们向服务器发送一个网址请求,服务器给咱们返回的可不止一个数据包,一般都是N个数据包。当我们看到源代码中没有时候,也许它正悄悄地通过Ajax传给我们了?

Ajax在网上有很多的解释,但是大家未必能理解。从服务器获得源代码数据,然后通过浏览器渲染执行JavaScript获得一些数据(音乐)。

这样说大家应该就懂了,那么咱们开始抓当前页面的包:

Python音乐爬虫完美绕过反爬

Ajax异步请求的数据,都会在XHR中。所以直接筛选就好了。这个包我已经抓到了,get请求然后看下返回的值。

Python音乐爬虫完美绕过反爬

果然就是这个包数据都是对应的,然后打开看看里面是否有音乐源文件地址:

Python音乐爬虫完美绕过反爬

并没有,但是有一个rid出现了两次。

分析(x4)

那么它是否是咱们音乐的ID(索引)值?

接着看下面的包:

Python音乐爬虫完美绕过反爬

这个get请求很关键,它的参数中利用到了咱们的rid这个值

而他返回值里正好有咱们的音乐源文件地址:

Python音乐爬虫完美绕过反爬

通过分析获取到音乐

通过咱们的分析,已经可以理清思路了。

首先抓取这个包获取到rid

Python音乐爬虫完美绕过反爬

然后传递rid进行这个包的请求获取到音乐文件地址

Python音乐爬虫完美绕过反爬

JavaScript绕过之参数冗余

Python音乐爬虫完美绕过反爬

可以看到这个rid获取的地址中有key值是url编码很轻松就可以解码:

import requests
keywords = '%E5%BE%80%E4%BA%8B%E9%9A%8F%E9%A3%8E'
print(requests.utils.unquote(keywords))
# 往事随风

而pn=1意思就是第一页嘛,30就是这一页总共30条音乐数据咯,1代表状态码请求成功,而最后reqId这个值如何获取呢?

Python音乐爬虫完美绕过反爬

有能力的自己去逆向JavaScript,而咱们这里直接把这里的参数都删除掉,同样可以访问到咱们的rid,为什么呢?

当你访问百度的时候

Python音乐爬虫完美绕过反爬

可以看到多余了很多你看不懂的参数,而这些参数实际上可以直接删除掉!

Python音乐爬虫完美绕过反爬

结果是一样的,这个就叫参数冗余。

CSRF攻击与防御

当咱们直接访问这个链接确出现这样的画面?

Python音乐爬虫完美绕过反爬

而咱们如果把请求头全部放到咱们的pycharm中利用Python模拟发送请求却可以成功(自行测试)

Python音乐爬虫完美绕过反爬

可以看到请求中有一个参数叫csrf,这个叫做防跨站点攻击。

这个就好理解了,当我们用浏览器直接访问的话,尽管可以带cookies,但是咱们是没法携带这个参数的。而当我们把请求头完整的复制在pycharm中Python运行的话,就可以携带这个参数,那么就可以访问。

目的就是保护此api防止任意情况下都可以随便访问。

而这个csrf参数不就是咱们cookies中的值么?那么是不是咱们首先需要获取cookies?因为cookies会过期阿,为了让你的程序永久有效,那么最好的办法就是自动获取cookies

总结

那么所有的原理都可以搞清楚了

首先访问首页获取cookies,然后绕过JavaScript删除多余的参数获取到rid,最后通过rid进行访问获取到音乐源地址(这里的参数也可以删除),最后保存数据!

全程干货,分析网站反扒手段,Python采集整站任意音乐!

代码

"""
author: 善念
date: 2021-04-12
"""
import requests
import jsonpath
from urllib.request import urlretrieve
import urllib.parse
 
 
def get_csrf():
    # 保持cookies 维持客户端与服务器之间的会话
 
    headers = {
        'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
        'Accept-Encoding': 'gzip, deflate',
        'Accept-Language': 'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7',
        'Cache-Control': 'no-cache',
        'Connection': 'keep-alive',
        # 'Cookie': 'Hm_lvt_cdb524f42f0ce19b169a8071123a4797=1618229629; _ga=GA1.2.1951895595.1618229638; _gid=GA1.2.369506281.1618229638; Hm_lpvt_cdb524f42f0ce19b169a8071123a4797=1618230532; kw_token=ZOMA0RIOLV',
        'Host': 'www.kuwo.cn',
        'Pragma': 'no-cache',
        'Upgrade-Insecure-Requests': '1',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.114 Safari/537.36',
    }
    s.get('http://www.kuwo.cn/', headers=headers)
 
    url = f'http://www.kuwo.cn/api/www/search/searchMusicBykeyWord?key={keyword}&pn=1&rn=30&httpsStatus=1&reqId=a3b6cb30-9b8a-11eb-bc04-b33703ed2ebb'
    headers = {
        'Accept': 'application/json, text/plain, */*',
        'Accept-Encoding': 'gzip, deflate',
        'Accept-Language': 'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7',
        'Cache-Control': 'no-cache',
        'Connection': 'keep-alive',
        # 'Cookie': 'Hm_lvt_cdb524f42f0ce19b169a8071123a4797=1618229629; _ga=GA1.2.1951895595.1618229638; _gid=GA1.2.369506281.1618229638; Hm_lpvt_cdb524f42f0ce19b169a8071123a4797=1618229710; kw_token=UTBATXE1HY',
        'csrf': s.cookies.get_dict()['kw_token'],
        'Host': 'www.kuwo.cn',
        'Pragma': 'no-cache',
        'Referer': f'http://www.kuwo.cn/search/list?key={keyword}',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.114 Safari/537.36',
 
 
    }
    r = s.get(url, headers=headers)
    print(r.text)
    rid = jsonpath.jsonpath(r.json(), '$..rid')[0]
    print(rid)
    return rid
 
 
def get_music_url(rid):
    url = f'http://www.kuwo.cn/url?format=mp3&rid={rid}&response=url&type=convert_url3&br=128kmp3&from=web&httpsStatus=1'
    headers = {
        'Accept': 'application/json, text/plain, */*',
        'Accept-Encoding': 'gzip, deflate',
        'Accept-Language': 'zh-CN,zh;q=0.9',
        'Cache-Control': 'no-cache',
        'Connection': 'keep-alive',
        # 'Cookie': 'Hm_lvt_cdb524f42f0ce19b169a8071123a4797=1618231398; _ga=GA1.2.52993118.1618231399; _gid=GA1.2.889494894.1618231399; Hm_lpvt_cdb524f42f0ce19b169a8071123a4797=1618231413; _gat=1; kw_token=VBM6N1XEG4P',
        'Host': 'www.kuwo.cn',
        'Pragma': 'no-cache',
        'Referer': f'http://www.kuwo.cn/search/list?key={keyword}',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.114 Safari/537.36',
    }
    music_url = s.get(url, headers=headers).json().get('url')
    print(music_url)
    return music_url
 
 
def get_music(music_url):
    urlretrieve(music_url, f'{urllib.parse.unquote(keyword)}'+'.mp3')
 
 
def go():
    rid = get_csrf()
    music_url = get_music_url(rid)
    get_music(music_url)
 
 
if __name__ == '__main__':
    s = requests.session()
    keyword = input('请输入您要下载的音乐名字:')
    keyword = urllib.parse.quote(keyword)
    go()

到此这篇关于Python音乐爬虫完美绕过反爬的文章就介绍到这了,更多相关Python爬取音乐内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
python将字符串转换成数组的方法
Apr 29 Python
Python中的深拷贝和浅拷贝详解
Jun 03 Python
Python下的Softmax回归函数的实现方法(推荐)
Jan 26 Python
python中模块查找的原理与方法详解
Aug 11 Python
Python内建模块struct实例详解
Feb 02 Python
pandas.loc 选取指定列进行操作的实例
May 18 Python
win7下python3.6安装配置方法图文教程
Jul 31 Python
python游戏地图最短路径求解
Jan 16 Python
Python参数类型以及常见的坑详解
Jul 08 Python
python的mysql数据库建立表与插入数据操作示例
Sep 30 Python
基于python计算并显示日间、星期客流高峰
May 07 Python
Django Admin 上传文件到七牛云的示例代码
Jun 20 Python
详解解Django 多对多表关系的三种创建方式
Aug 23 #Python
一些让Python代码简洁的实用技巧总结
Aug 23 #Python
一篇文章搞懂python混乱的切换操作与优雅的推导式
Aug 23 #Python
Python学习开发之图形用户界面详解
Aug 23 #Python
利用Python读取微信朋友圈的多种方法总结
Aug 23 #Python
教你使用一行Python代码玩遍童年的小游戏
一文搞懂Python Sklearn库使用
You might like
《星际争霸》各版本雷兽特点图文解析 雷兽不同形态一览
2020/03/02 星际争霸
PHP json_decode函数详细解析
2014/02/17 PHP
Laravel使用RabbitMQ的方法示例
2019/06/18 PHP
25个非常棒的jQuery滑块插件和教程小结
2011/09/02 Javascript
修复IE9&safari 的sort方法
2011/10/21 Javascript
jQuery中focus事件用法实例
2014/12/26 Javascript
JavaScript调用客户端Java程序的方法
2015/07/27 Javascript
jQuery 3 中的新增功能汇总介绍
2016/06/12 Javascript
easyui form validate总是返回false的原因及解决方法
2016/11/07 Javascript
浅析javascript中的Event事件
2016/12/09 Javascript
解决iview打包时UglifyJs报错的问题
2018/03/07 Javascript
微信公众平台 客服接口发消息的实现代码(Java接口开发)
2019/04/17 Javascript
微信小程序用户授权弹窗 拒绝时引导用户重新授权实现
2019/07/29 Javascript
深入webpack打包原理及loader和plugin的实现
2020/05/06 Javascript
Node.js API详解之 console模块用法详解
2020/05/12 Javascript
使用python实现正则匹配检索远端FTP目录下的文件
2015/03/25 Python
浅析Python多线程下的变量问题
2015/04/28 Python
Python的Django框架中的数据过滤功能
2015/07/17 Python
python3+PyQt5实现文档打印功能
2018/04/24 Python
在scrapy中使用phantomJS实现异步爬取的方法
2018/12/17 Python
在Python运行时动态查看进程内部信息的方法
2019/02/22 Python
python实现QQ空间自动点赞功能
2019/04/09 Python
Python中Flask-RESTful编写API接口(小白入门)
2019/12/11 Python
GDAL 矢量属性数据修改方式(python)
2020/03/10 Python
python脚本第一行如何写
2020/08/30 Python
大学生实习自我鉴定
2013/12/11 职场文书
车间统计员岗位职责
2014/01/05 职场文书
2014道德模范事迹材料
2014/02/16 职场文书
小学数学教学经验交流材料
2014/05/22 职场文书
中学教代会开幕词
2016/03/04 职场文书
python绘制箱型图
2021/04/27 Python
Python数据分析之pandas读取数据
2021/06/02 Python
python基于turtle绘制几何图形
2021/06/15 Python
JavaScript高级程序设计之变量与作用域
2021/11/17 Javascript
Python实现GIF动图以及视频卡通化详解
2021/12/06 Python
在vue中import()语法不能传入变量的问题及解决
2022/04/01 Vue.js