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中的jquery PyQuery库使用小结
May 13 Python
python批量提交沙箱问题实例
Oct 08 Python
使用Python读写及压缩和解压缩文件的示例
Jul 08 Python
Python实现的下载网页源码功能示例
Jun 13 Python
运行django项目指定IP和端口的方法
May 14 Python
Django1.9 加载通过ImageField上传的图片方法
May 25 Python
Python实现爬取马云的微博功能示例
Feb 16 Python
python 计算数据偏差和峰度的方法
Jun 29 Python
Python 的AES加密与解密实现
Jul 09 Python
Python Collatz序列实现过程解析
Oct 12 Python
pytorch 使用加载训练好的模型做inference
Feb 20 Python
全网最全python库selenium自动化使用详细教程
Jan 12 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
将RTF格式的文件转成HTML并在网页中显示的代码
2006/10/09 PHP
phpMyAdmin 安装配置方法和问题解决
2009/06/08 PHP
PHP与MongoDB简介|安全|M+PHP应用实例详解
2013/06/17 PHP
PHP网页游戏学习之Xnova(ogame)源码解读(三)
2014/06/23 PHP
php mysql_real_escape_string addslashes及mysql绑定参数防SQL注入攻击
2016/12/23 PHP
利用Laravel事件系统如何实现登录日志的记录详解
2017/05/20 PHP
PHP微信公众号开发之微信红包实现方法分析
2017/07/14 PHP
JavaScript与DropDownList 区别分析
2010/01/01 Javascript
niceTitle 基于jquery的超链接提示插件
2010/05/31 Javascript
JavaScript 原型链学习总结
2010/10/29 Javascript
jquery判断元素是否隐藏的多种方法
2014/05/06 Javascript
javascript运算符——位运算符全面介绍
2016/07/14 Javascript
js的各种排序算法实现(总结)
2016/07/23 Javascript
JS 事件绑定、事件监听、事件委托详细介绍
2016/09/28 Javascript
如何使用Bootstrap创建表单
2017/03/29 Javascript
基于jstree使用AJAX请求获取数据形成树
2017/08/29 Javascript
Nodejs下使用gm圆形裁剪并合成图片的示例
2018/02/22 NodeJs
vue移动端弹框组件的实例
2018/09/25 Javascript
浅谈vue中resetFields()使用注意事项
2020/08/12 Javascript
[02:36]DOTA2亚洲邀请赛小组赛精彩集锦:奇迹哥卡尔秀翻全场
2017/03/28 DOTA
python下如何让web元素的生成更简单的分析
2008/07/17 Python
python计数排序和基数排序算法实例
2014/04/25 Python
Python实现从百度API获取天气的方法
2015/03/11 Python
Python中enumerate函数代码解析
2017/10/31 Python
python对象与json相互转换的方法
2019/05/07 Python
tensorflow指定CPU与GPU运算的方法实现
2020/04/21 Python
python针对Oracle常见查询操作实例分析
2020/04/30 Python
Django返回HTML文件的实现方法
2020/09/17 Python
python爬虫中采集中遇到的问题整理
2020/11/27 Python
纯HTML5+CSS3制作生日蛋糕代码
2016/11/16 HTML / CSS
波兰灯具、照明和LED购物网站:Lampy.pl
2019/03/11 全球购物
荷兰在线啤酒店:Beerwulf
2019/08/26 全球购物
市场营销专业大学生职业生涯规划文
2014/03/06 职场文书
聊一聊Redis与MySQL双写一致性如何保证
2021/06/26 Redis
使用python将HTML转换为PDF pdfkit包(wkhtmltopdf) 的使用方法
2022/04/21 Python
vue elementUI批量上传文件
2022/04/26 Vue.js