Python【Network/XHR/json】
#####################################################################
制定一个目标(爬取周杰伦的歌曲清单);
根据目标,确认一个方案(爬取qq音乐);
带着方案,去分析它的网站结构;最后去写代码
#####################################################################
什么是network
调用“检查”(ctrl+shift+i)工具,然后点击network
记录在当前页面上发生的所有请求。
现在看上去好像空空如也的样子,这是因为network记录的是实时网络请求。
现在网页都已经加载完成,所以不会有东西。
点击一下刷新,浏览器会重新访问网络,这样就会有记录
浏览器总是在向服务器,发起各式各样的请求。
当这些请求完成,它们会一起组成我们在elements中看到的网页源代码
一般来说,都是这种第0个请求先启动了
其他的请求才会关联启动,一点点地将网页给填充起来
也有一些网页,直接把所有的关键信息都放在第0个请求里
方法:
先找到哪一个请求当中。再用requests库,去模拟这个请求
+++++++++++++++++++++++++++++++++++++++++++++++++++++
network怎么用
第一行
all(查看全部)/xhr(仅查看xhr,我们等会重点讲它)/doc(document,第0个请求一般在这里),
有时候也会看看:img(仅查看图片)/media(仅查看媒体文件)/other(其他)。
最后,js和css,则是前端代码,负责发起请求和页面实现;font是文字的字体;
而理解ws和manifest,需要网络编程的知识,倘若不是专门做这个,你不需要了解
第二行
是一个时间轴。记录什么时间,有哪些请求
第三行
统计:有多少个请求,一共多大,花了多长时间
############################################################
什么是xhr?
把鼠标在xhr上悬停,你可以看到它的完整表述是xhr and fetch
#了解即可:ajax技术 应用这种技术,好处是显而易见的——更新网页内容,而不用重新加载整个网页。又省流量又省时间
工作的时候,会创建一个xhr(或是fetch)对象,
然后利用xhr对象来实现,服务器和浏览器之间传输数据。
在这里,xhr和fetch并没有本质区别,只是fetch出现得比xhr更晚一些,所以对一些开发人员来说会更好用,但作用都是一样的
+++++++++++++++++++++
xhr怎么请求?
列子:
点击xhr按钮。
网页里一共有10个xhr或fetch,我们要从里面找出带有歌单的那一个(尝试阅读它们的名字client_search)
从左往右分别是:headers:标头(请求信息)、preview:预览、response:原始信息、timing:时间。
点击preview按照这样的顺序:data-song-list-0-name,就能看到歌名
#最左侧的headers,点击它-general-requests url-浏览器中打开链接(字典层层嵌套),比较难看
直接看preview,按照这样的顺序:data-song-list-0-name,歌曲名就在这里,它的键是name
xhr是一个字典,键data对应的值也是一个字典;
在该字典里,键song对应的值也是一个字典;
在该字典里,键list对应的值是一个列表;
在该列表里,一共有20个元素;
每一个元素都是一个字典;在每个字典里,键name的值,对应的是歌曲名。
xhr{data:{song:{list:[name:{歌曲名}
1 import requests 2 3 # 引用requests库 4 5 res = 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=60997426243444153&t=0&aggr=1&cr=1&catzhida=1&lossless=0&flag_qc=0&p=1&n=20&w=%e5%91%a8%e6%9d%b0%e4%bc%a6&g_tk=5381&loginuin=0&hostuin=0&format=json&incharset=utf8&outcharset=utf-8¬ice=0&platform=yqq.json&neednewcode=0') 6 7 #url地址点击xhr --name--copy link address 或者复制request url 8 9 # 调用get方法,下载这个字典 10 11 print(res.text) 12 13 # 把它打印出来 结果不是我们想要的列表/字典,数据取不出来
######################################################
json是什么?
json是一种特殊的字符串,这种字符串特殊在它的写法——它是用列表/字典的语法写成的
和html一样,常用来做网络数据传输
json的数据类型是“文本”,在python语言当中,我们把它称为字符串
不是所有的编程语言都能读懂python里的数据类型(如,列表/字符串),
但是所有的编程语言,都支持文本(在python中,用字符串这种数据类型来表示文本)这种最朴素的数据类型
json数据能实现,跨平台,跨语言工作。
json和xhr之间的关系
xhr用于传输数据,它能传输很多种数据,json是被传输的一种数据格式
可以将json格式的数据,转换成正常的列表/字典,也可以将列表/字典,转换成json
+++++++++++++++++++++++++++++++++++++++++++++++++++++
json数据如何解析?
搜索“requests 官方文档”
requests 中也有一个内置的 json 解码器,助你处理 json 数据:
>>> import requests
>>> r = requests.get('https://api.github.com/events')
>>> r.json()
[{u'repository': {u'open_issues': 0, u'url': 'https://github.com/...
如果 json 解码失败, r.json() 就会抛出一个异常。例如,响应内容是 401 (unauthorized),尝试访问 r.json() 将会抛出 valueerror: no json object could be decoded 异常。
需要注意的是,成功调用 r.json() 并**不**意味着响应的成功。有的服务器会在失败的响应中包含一个 json 对象(比如 http 500 的错误细节)。
这种 json 会被解码返回。要检查请求是否成功,请使用 r.raise_for_status() 或者检查 r.status_code 是否和你的期望相同。
1 import requests 2 3 # 引用requests库 4 5 res_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=60997426243444153&t=0&aggr=1&cr=1&catzhida=1&lossless=0&flag_qc=0&p=1&n=20&w=%e5%91%a8%e6%9d%b0%e4%bc%a6&g_tk=5381&loginuin=0&hostuin=0&format=json&incharset=utf8&outcharset=utf-8¬ice=0&platform=yqq.json&neednewcode=0') 6 7 # 调用get方法,下载这个字典 8 9 json_music = res_music.json() 10 11 # 使用json()方法,将response对象,转为列表/字典 12 13 print(type(json_music)) 14 15 # 打印json_music的数据类型 <class 'dict'>
1 import requests 2 3 # 引用requests库 4 5 res_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=60997426243444153&t=0&aggr=1&cr=1&catzhida=1&lossless=0&flag_qc=0&p=1&n=20&w=%e5%91%a8%e6%9d%b0%e4%bc%a6&g_tk=5381&loginuin=0&hostuin=0&format=json&incharset=utf8&outcharset=utf-8¬ice=0&platform=yqq.json&neednewcode=0') 6 7 # 调用get方法,下载这个字典 8 9 json_music = res_music.json() 10 11 # 使用json()方法,将response对象,转为列表/字典 12 13 list_music = json_music['data']['song']['list'] 14 15 # 一层一层地取字典,获取歌单列表 16 17 for music in list_music: 18 19 # list_music是一个列表,music是它里面的元素 20 21 print(music['name']) 22 23 # 以name为键,查找歌曲名 24 25 print('所属专辑:'+music['album']['name']) 26 27 # 查找专辑名 28 29 print('播放时长:'+str(music['interval'])+'秒') 30 31 # 查找播放时长 32 33 print('播放链接:https://y.qq.com/n/yqq/song/'+music['mid']+'.html\n\n') 34 35 # 查找播放链接
扩展json
1 import json 2 3 # 引入json模块 4 5 a = [1,2,3,4] 6 7 # 创建一个列表a。 8 9 b = json.dumps(a) 10 11 # 使用dumps()函数,将列表a转换为json格式的字符串,赋值给b。 12 13 print(b) 14 15 # 打印b。 16 17 print(type(b)) 18 19 # 打印b的数据类型。 20 21 22 23 c = json.loads(b) 24 25 # 使用loads()函数,将json格式的字符串b转为列表,赋值给c。 26 27 print(c) 28 29 # 打印c。 30 31 print(type(c)) 32 33 # 打印c的数据类型。