Python音乐爬虫完美绕过反爬
作者:落伍的码农 发布时间:2022-12-30 06:53:45
前言
大家好,我叫善念。
这是我的第二篇博客,也是第一篇技术博客,希望大家多多支持,让我更加有动力去更新一些python爬虫类的案例教程。
开始
确立目标网址:点击进入
进入到跳转页面:
可以看到出现了咱们需要的一些音乐
分析(x0)
这些音乐的源文件地址是否在咱们的网页元素中,然后再查看网页源代码中是否有咱们需要的内容。(注:网页元素与网页源代码不一定是一样的,网页元素是经过浏览器渲染后的源代码,而源代码纯粹就是服务器给咱们传送过来的原始数据)
网页元素中只有封面图片的资源,没用音频源文件地址:
网页源代码中同样没有咱们需要的内容:
分析(x1)
其实没有才正常(这种大型网站的数据不会让你这么轻易抓取)....不过是带大家走一遍流程,对别的网站也要这样分析
那么咱们开始播放音乐抓包,看是否能抓到数据:
果然是经过触发播放按钮后,服务器传给咱们客户端的。(ajax)
而咱们抓到的这个源文件地址
除了这两段外,其它的应该都是固定死的。
分析(x2)
那么我假设这两段是从我开始访问这首歌曲页面的时候生成的,比如后面那串数字为这首音乐在服务器数据库中的对应的一个ID值呢?
假设是合理的,不过由于咱们前面已经查看过源代码和网页元素中找不到这些值,我就不在这里浪费时间了。
分析(x3)
这里我和大家讲一下,咱们向服务器发送一个网址请求,服务器给咱们返回的可不止一个数据包,一般都是N个数据包。当我们看到源代码中没有时候,也许它正悄悄地通过Ajax传给我们了?
Ajax在网上有很多的解释,但是大家未必能理解。从服务器获得源代码数据,然后通过浏览器渲染执行JavaScript获得一些数据(音乐)。
这样说大家应该就懂了,那么咱们开始抓当前页面的包:
Ajax异步请求的数据,都会在XHR中。所以直接筛选就好了。这个包我已经抓到了,get请求然后看下返回的值。
果然就是这个包数据都是对应的,然后打开看看里面是否有音乐源文件地址:
并没有,但是有一个rid
出现了两次。
分析(x4)
那么它是否是咱们音乐的ID(索引)值?
接着看下面的包:
这个get请求很关键,它的参数中利用到了咱们的rid
这个值
而他返回值里正好有咱们的音乐源文件地址:
通过分析获取到音乐
通过咱们的分析,已经可以理清思路了。
首先抓取这个包获取到rid
然后传递rid
进行这个包的请求获取到音乐文件地址
JavaScript绕过之参数冗余
可以看到这个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
这个值如何获取呢?
有能力的自己去逆向JavaScript,而咱们这里直接把这里的参数都删除掉,同样可以访问到咱们的rid
,为什么呢?
当你访问百度的时候
可以看到多余了很多你看不懂的参数,而这些参数实际上可以直接删除掉!
结果是一样的,这个就叫参数冗余。
CSRF攻击与防御
当咱们直接访问这个链接确出现这样的画面?
而咱们如果把请求头全部放到咱们的pycharm中利用Python模拟发送请求却可以成功(自行测试)
可以看到请求中有一个参数叫csrf
,这个叫做防跨站点攻击。
这个就好理解了,当我们用浏览器直接访问的话,尽管可以带cookies,但是咱们是没法携带这个参数的。而当我们把请求头完整的复制在pycharm中Python运行的话,就可以携带这个参数,那么就可以访问。
目的就是保护此api防止任意情况下都可以随便访问。
而这个csrf参数不就是咱们cookies中的值么?那么是不是咱们首先需要获取cookies?因为cookies会过期阿,为了让你的程序永久有效,那么最好的办法就是自动获取cookies
代码
"""
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()
来源:https://blog.csdn.net/Python_shannian/article/details/119925303
猜你喜欢
- 题目:给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。示例:示例 1:输入: “abcabcbb”输出: 3解释: 因为无重
- Pandas之drop_duplicates:去除重复项方法DataFrame.drop_duplicates(subset=None, k
- MySQL GUI Tools是一套图形化桌面应用工具套装,可以用来管理MySQL服务器。该套装工具包含三个工具:MySQL Query B
- 项目意义如果你想在支付宝蚂蚁森林收集很多能量种树,为环境绿化出一份力量,又或者是想每天称霸微信运动排行榜装逼,却不想出门走路,那么该pyth
- 不少小伙伴认为,直接去操作excel,比我们利用各种代码数据去处理,直接又简单,不那么花里胡哨,但是在代码上,处理数据,直接的软件操作是行不
- 在日常工作中,除了会涉及到使用Python处理文本文件,有时候还会涉及对压缩文件的处理。通常会涉及到的压缩文件格式有:rar:Windows
- 1.下载Python官网:传送门根据自己的主机环境下载python2.安装下载完后直接安装,安装时自定义安装路径,这里路径要记下来我的安装路
- 今天在群里,熊猫君提议整理一个帖子,一方面为初学者提供一个入门指南,另一方面也象借此和已经在从事这个行业进行一点交流。下面是我从事这个行当多
- 为庆祝jQuery的四周年生日,jQuery官方团队正式发布了jQuery 1.4版本。在这个版本中,jQuery官方团队做了大量的编码、测
- 1、在 Windows 设置临时环境变量 cmd命令窗口 输入 path=%path%;E:\soft\python-3.5.2-embed
- asp中使用addnew方法添加一条记录后,我们经常使用取得自递增的ID,而使用bookmark很容易实现这样的功能。rs.open&nbs
- 1.我们可以为每一个实例对象增加方法。也就是说我们在每次使用‘类'之外的方法时候,都需要创建一次。 function D
- 网站可用性是任何网站的基本要素,而可用的导航更是网站所必需的要素之一。导航决定了用户如何与网站进行交互。如果没有了可用的导航,那么网站内容就
- 题目:解法一:比较元素是否相等思路说明:这种应该是普通人最先想到的解法,先获取到数组之后进行有小到大排序,然后初始化一个min=0(代表新数
- 目录实验环境依赖项安装编程实现浏览器有一个可以用于展示网页的窗口代码总结实验环境操作系统:Linux Mint编辑器:vim编程语言:pyt
- 1. 服务器优化优化原则:内存里的数据要比磁盘上的数据访问起来快;站数据尽可能长时间地留在内存里能减少磁盘读写活动的工作量;让索引信息留在内
- GO 语言的 for…range 能做什么呢?for…range 如何使用 ?for…range 的返回
- 网络安全问题很重要,尤其是保证数据安全,遇到很多在写接口的程序员直接都是明文数据传输,在我看来这是很不专业的。本人提倡经过接口的数据都要进行
- scriptlet的使用jsp页面中分三种scriptlet:第一种:<% %> 可以在里面写java的代码。定义java变量以
- 由于数据文件平时在数据库运行的时候处于使用状态,故当数据库处于打开状态时,管理员是无法重命名数据文件名字的。那么一定要更改这个数据文件的名字