通过关键词采集文章采集api(【每日一题】网页源代码的案例教程(二) )

优采云 发布时间: 2021-08-30 23:13

  通过关键词采集文章采集api(【每日一题】网页源代码的案例教程(二)

)

  内容

  前言

  大家好,我叫山念。

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

  

  开始

  建立目标网址:点击进入

  

  进入跳转页面:

  

  你可以看到我们需要一些音乐

  分析(x0)

  这些音乐的源文件地址是否在我们的网页元素中,然后检查网页源代码中是否收录我们需要的内容。 (注:网页元素和网页源代码不一定相同。网页元素是浏览器渲染的源代码,源代码纯粹是服务器发送给我们的原创数据)

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

  

  网页的源代码中也没有我们需要的东西:

  

  分析(x1)

  其实没有也很正常(网站这么大的数据不会让你这么轻易就抢到了.....只是带大家走一遍流程,分析其他网站这样的

  那我们开始播放音乐来抓包,看看能不能抓到数据:

  

  果然,在播放按钮被触发后,服务器将其发送给我们的客户端。 (阿贾克斯)

  还有我们抓到的源文件地址

  

  除了这两个段落,其他的都应该修复。

  分析(x2)

  然后我假设这两个段落是我第一次访问这首歌的页面时生成的。比如这首音乐在服务器数据库中的ID值是多少?

  假设是合理的,但由于我们已经检查了源代码并且网页元素找不到这些值,我不会在这里浪费时间。

  分析(x3)

  这里告诉你,我们向服务器发送一个URL请求,服务器返回给我们的数据包不止一个,一般是N个数据包。当我们看到没有源代码时,可能是通过ajax悄悄传递给我们的?

  Ajax 网上有很多解释,但大家可能看不懂。从服务器获取源代码数据,然后执行JavaScript通过浏览器渲染获取一些数据(音乐)。

  这样大家应该就明白了,接下来我们开始抓取当前页面的包:

  

  Ajax 异步请求数据将在 XHR 中。所以直接过滤就好了。我抓到了这个包,获取请求并查看返回值。

  

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

  

  没有,但是出现了两次。

  分析(x4)

  那是我们音乐的ID(index)值吗?

  看下面的包:

  

  这个get请求很重要,它在参数中使用了我们的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 参数不是我们 cookie 中的值吗?那么我们需要先获取cookie吗?因为cookies会过期,为了让你的程序永远有效,那么最好的办法就是自动获取cookies

  总结

  那么所有的原理就可以想通了

  先访问首页获取cookies,然后绕过JavaScript删除多余的参数进行摆脱,最后通过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()

  

  文章到此结束,感谢阅读,但我想对读者说几句。

  emmmmm今天无话可说——我心里没有女人,代码自然☺

  

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线