# Author:Nimo_Ding
'''
目标:
爬取周杰伦的歌曲清单
'''
import requests
from bs4 import BeautifulSoup
headers = {
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36'}
url='https://y.qq.com/portal/search.html#page=1&searchid=1&remoteplace=txt.yqq.top&t=song&w=%E5%91%A8%E6%9D%B0%E4%BC%A6'
music=requests.get(url,headers=headers)
# print(music.text)
# 这里我们从源代码中并没有找到任何歌曲名单。
# 接下来要从Network里面去查找
# Elements:网页源代码
# Network:记录当前页面上发生的所有请求,是实时请求,刷新一下,浏览器会重新访问网络,就会有记录
# 当这些请求完成会组成我们在Elements中看到的网页源代码。
# 为什么刚才无法拿到歌曲清单的代码,是因为刚刚的代码只是所有请求中的第一个请求(准确来说是第0个)
# 而这第0个请求search.html中不包含歌曲清单。点击search.html里的response,就是这个请求的结果。
# 一般都是第0个请求先启动,其他请求才会关联启动。
# 当然也有一些网页直接把所有关键信息都放在第0个请求中,尤其是比较老或轻量的网站,我们用requests和BeautifulSoup就能解决。
'''
Network使用方法:
0、启用Network监控,默认是高亮打开的
1、清空面板信息,灰色圆圈是清空
2、ALL查看全部
3、XHR仅查看XHR
4、勾选Preserve Log - 保留请求日志,如果不勾选,当页面发生跳转记录就会被清空。
这里是对请求进行分类:
ALL:查看全部
XHR:仅查看XHR
Doc:Document,第0个请求一般在这里
Img:仅查看图片
Media:仅查看媒体文件
JS和CSS:前端代码,负责发起请求和页面实现
Font:字体
WS和Manifest:网络编程相关知识,无需了解
请求的信息:
name:名字
status:请求状态,2xx表示成功
type:请求的类型-XHR/Doc/Img
size:数据的大小
time:请求的耗时
waterfall:瀑布流,用于描述每个请求的起止时间
在Network中,XHR是非常重要的一个请求(当你鼠标在XHR上悬停是,显示的是XHR and Fetch)
我们平时使用浏览器上网的时候,经常有这样的情况:
浏览器上方,它所访问的网址没变,但是网页里却新加了内容。
典型代表:
如购物网站,下滑自动加载出更多商品。
在线翻译网站,输入中文实时变英文。
你正在使用的教学系统,每点击一次Enter就有新的内容弹出。
这个,叫做Ajax技术。好处是:更新网页内容,而不用重新加载整个网页,省流量省时间。
这种技术在工作时会创建一个XHR(或Fetch)对象,然后利用XHR对象来实现服务器和浏览器之间传输数据。
XHR和Fetch并无本质上的区别,只是Fetch出现比XHR更晚,会开发人员来说好用些。
歌曲清单如果不在网页源代码里,而且也不是图片,不是媒体文件,自然只会是在XHR里。
找到client_search
先来看右上方框里标号的内容,从左往右分别是:
Headers:标头(请求信息)、
Preview:预览、
Response:响应、
Cookies:Cookies、
Timing:时间
再看Headers里的General
Request URL: https://c.y.qq.com/soso/fcgi-bin/client_search_cp?ct=24&qqmusic_ver=1298&new_json=1&remoteplace=txt.yqq.song&searchid=68635961138684881&t=0&aggr=1&cr=1&catZhida=1&lossless=0&flag_qc=0&p=1&n=10&w=%E5%91%A8%E6%9D%B0%E4%BC%A6&g_tk_new_20200303=5381&g_tk=5381&loginUin=0&hostUin=0&format=json&inCharset=utf8&outCharset=utf-8¬ice=0&platform=yqq.json&needNewCode=0
Request Method: GET
Status Code: 200
Remote Address: 127.0.0.1:51290
Referrer Policy: no-referrer-when-downgrade
所以我们用Request URL这个链接去获取数据
'''
import json
music=requests.get('https://c.y.qq.com/soso/fcgi-bin/client_search_cp?ct=24&qqmusic_ver=1298&new_json=1&remoteplace=txt.yqq.song&searchid=68635961138684881&t=0&aggr=1&cr=1&catZhida=1&lossless=0&flag_qc=0&p=1&n=10&w=%E5%91%A8%E6%9D%B0%E4%BC%A6&g_tk_new_20200303=5381&g_tk=5381&loginUin=0&hostUin=0&format=json&inCharset=utf8&outCharset=utf-8¬ice=0&platform=yqq.json&needNewCode=0')
res=music.text # 但是这样得到的是字符串不是字典。
# 因此引入json,json是一种数据交换的语法,是一种规范数据传输的格式
# json可支持跨平台跨语言工作
# res_dic=json.loads(res) # 这样也是同样效果
# print(music.json()) # 这样可直接拿到字典格式。
music_dic=music.json()
for i in music_dic['data']['song']['list']:
print('歌曲名:{}\n所属专辑:\n{}播放时长:{}\n播放链接:\n{}\n'.
format(i['name'],
i['album']['name'],
str(i['interval'])+'秒',
'https://y.qq.com/n/yqq/song/'+i['mid']+'.html'))