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中线程编程之threading模块的使用详解
Jun 23 Python
Python使用pymysql小技巧
Jun 04 Python
python面向对象_详谈类的继承与方法的重载
Jun 07 Python
Python爬虫实现全国失信被执行人名单查询功能示例
May 03 Python
python寻找list中最大值、最小值并返回其所在位置的方法
Jun 27 Python
PyCharm代码提示忽略大小写设置方法
Oct 28 Python
Python3列表内置方法大全及示例代码小结
May 10 Python
在Python中表示一个对象的方法
Jun 25 Python
Django Celery异步任务队列的实现
Jul 24 Python
python禁用键鼠与提权代码实例
Aug 16 Python
VSCode基础使用与VSCode调试python程序入门的图文教程
Mar 30 Python
教你怎么用Python操作MySql数据库
May 31 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
判“新”函数:得到今天与明天的秒数
2006/10/09 PHP
php实现的短网址算法分享
2014/06/20 PHP
php获取目录下所有文件及目录(多种方法)(推荐)
2019/05/14 PHP
PHP封装cURL工具类与应用示例
2019/07/01 PHP
tp5框架前台无限极导航菜单类实现方法分析
2020/03/29 PHP
Laravel 修改验证异常的响应格式实例代码详解
2020/05/25 PHP
js验证表单大全
2006/11/25 Javascript
JavaScript经典效果集锦
2010/07/06 Javascript
JS模拟面向对象全解(二、类型与赋值)
2011/07/13 Javascript
javascript定时变换图片实例代码
2013/03/17 Javascript
node.js实现BigPipe详解
2014/12/05 Javascript
javascript实现的图片切割多块效果实例
2015/05/07 Javascript
从重置input file标签中看jQuery的 .val() 和 .attr(“value”) 区别
2016/06/12 Javascript
JavaScript实现点击文本自动定位到下拉框选中操作
2016/06/15 Javascript
jQuery多级联动下拉插件chained用法示例
2016/08/20 Javascript
vue2 如何实现div contenteditable=“true”(类似于v-model)的效果
2017/02/08 Javascript
Nodejs--post的公式详解
2017/04/29 NodeJs
angularJs复选框checkbox选中进行ng-show显示隐藏的方法
2018/10/08 Javascript
vue父子组件通信的高级用法示例
2019/08/29 Javascript
Echarts实现多条折线可拖拽效果
2019/12/19 Javascript
python实现的登陆Discuz!论坛通用代码分享
2014/07/11 Python
python3下使用cv2.imwrite存储带有中文路径图片的方法
2018/05/10 Python
python获取文件真实链接的方法,针对于302返回码
2018/05/14 Python
解决Pycharm中import时无法识别自己写的程序方法
2018/05/18 Python
Python基础之函数基本用法与进阶详解
2020/01/02 Python
Pyspark获取并处理RDD数据代码实例
2020/03/27 Python
Matplotlib 折线图plot()所有用法详解
2020/07/28 Python
Python selenium实现断言3种方法解析
2020/09/08 Python
Urban Outfitters美国官网:美国生活方式品牌
2016/08/26 全球购物
全球速卖通西班牙站:AliExpress西班牙
2017/10/30 全球购物
工作个人的自我评价
2014/01/14 职场文书
行政助理岗位职责范本
2015/04/11 职场文书
演讲开场白台词大全
2015/05/29 职场文书
2015重阳节座谈会主持词
2015/07/30 职场文书
如何撰写创业策划书
2019/06/27 职场文书
Android Rxjava3 使用场景详解
2022/04/07 Java/Android