第7课 Network和Json模块

一、准备工作

1. 当接手一个新项目,开发人员们并不会一上来就去写代码,他们会先去思考这个项目应当如何实现。

2. 如果说我们是要爬取周杰伦的歌,那么首先要思考的是:哪家网站,拥有周杰伦的歌曲版权?

3. 获取这个问题答案的方法有两种:其一是自己上网搜,其二是听我这个资深乐迷讲——答案是QQ音乐。

4. 首先,我们先去QQ音乐的官网,看看它的robots协议https://y.qq.com/robots.txt

5. 我们来进入QQ音乐的官网首页:https://y.qq.com,在索框内输入“周杰伦”,然后点击回车。此时,页面会发生跳转,你能看到,我们想要的歌曲信息,就在这个页面里。它的网址会是: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

6. 根据我们已经学过的知识,我们可以借助requests和BeautifulSoup,来爬取想要的数据。根据爬虫四步,我们会利用requests.get()去请求该网址;使用BeautiSoup对请求结果进行解析;利用find_all方法拿到我们想要的标签;提取歌曲清单。

二、代码实现,发现问题

import requests

from bs4 import BeautifulSoup

res_music=requests.get('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')# 请求html,得到response

bs_music=BeautifulSoup(res_music.text,'html.parser')# 解析

htmllist_music=bs_music.find_all('a',class_='js_song')# 查找class属性值为“js_song”的a标签,得到一个由标签组成的列表

for music in list_music:# 对查找的结果执行循环

print(music['title'])

print(res_music.text)

#网页源代码里根本没有我们想要的歌曲清单。

已经验证不是代码本身的问题,但目标却未能得到实现。我们就得往前回滚一步:思考,是不是上一步的分析出了问题?

想找到答案,需要用到一项新技能——翻找Network!

三、 重新分析,关于Network

1. 我们先去看看Network的页面。

在你刚才打开的QQ音乐页面,调用“检查”(ctrl+shift+i)工具,然后点击Network。

2. Network的功能是:记录在当前页面上发生的所有请求。现在看上去好像空空如也的样子,这是因为Network记录的是实时网络请求。现在网页都已经加载完成,所以不会有东西。

3. 找到这个页面的第0个请求:search.html,然后点击它。它就是我们刚刚用requests.get()获取到的网页源代码,它里面不包含歌曲清单。

4. 为了成功抓取到歌曲清单,我们得先找到,歌名藏在哪一个请求当中。再用requests库,去模拟这个请求。

5. 第0行的左侧,红色的圆钮是启用Network监控(默认高亮打开),灰色圆圈是清空面板上的信息。右侧勾选框Preserve log,它的作用是“保留请求日志”。如果不点击这个,当发生页面跳转的时候,记录就会被清空。所以,我们在爬取一些会发生跳转的网页时,会点亮它。

第1行,是对请求进行分类查看。我们最常用的是:ALL(查看全部)/XHR(仅查看XHR,我们等会重点讲它)/Doc(Document,第0个请求一般在这里),有时候也会看看:Img(仅查看图片)/Media(仅查看媒体文件)/Other(其他)。最后,JS和CSS,则是前端代码,负责发起请求和页面实现;Font是文字的字体;而理解WS和Manifest,需要网络编程的知识,倘若不是专门做这个,你不需要了解。

夹在第2行和第1行中间的,是一个时间轴。记录什么时间,有哪些请求。而第2行,就是各个请求,你可以看下面这张表来理解。

6. 什么是XHR?在Network中,有一类非常重要的请求叫做XHR(当你把鼠标在XHR上悬停,你可以看到它的完整表述是XHR and Fetch)。

我们平时使用浏览器上网的时候,经常有这样的情况:浏览器上方,它所访问的网址没变,但是网页里却新加了内容。

典型代表:如购物网站,下滑自动加载出更多商品。在线翻译网站,输入中文实时变英文。比如,你正在使用的教学系统,每点击一次Enter就有新的内容弹出。

这个,叫做Ajax技术(技术本身和爬虫关系不大,在此不做展开,你可以通过搜索了解)。应用这种技术,好处是显而易见的——更新网页内容,而不用重新加载整个网页。又省流量又省时间的,何乐而不为。

如今,比较新潮的网站都在使用这种技术来实现数据传输。只剩下一些特别老,或是特别轻量的网站,还在用老办法——加载新的内容,必须要跳转一个新网址。

这种技术在工作的时候,会创建一个XHR(或是Fetch)对象,然后利用XHR对象来实现,服务器和浏览器之间传输数据。在这里,XHR和Fetch并没有本质区别,只是Fetch出现得比XHR更晚一些,所以对一些开发人员来说会更好用,但作用都是一样的。

显而易见,对照前面的表单。我们的歌曲清单不在网页源代码里,而且也不是图片,不是媒体文件,自然只会是在XHR里。我们现在去找找看,点击XHR按钮。

client_search(客户端搜索)……,我们来点击它。

出现了如上图这样的一个窗口,我们先来看右上方框里标号的内容,从左往右分别是:Headers:标头(请求信息)、Preview:预览、Response:响应、Cookies:Cookies、Timing:时间。

点击Preview,你能在里面发现我们想要的信息:歌名就藏在里面!

四、代码实现

1. 回到原网址,直接用Preview来看就好。列表和字典在此都会有非常清晰的结构,层层展开。我们一层一层地点开,按照这样的顺序:data-song-list-0-name。

2. 歌曲名就在这里,它的键是name。理解这句话:这个XHR是一个字典,键data对应的值也是一个字典;在该字典里,键song对应的值也是一个字典;在该字典里,键list对应的值是一个列表;在该列表里,一共有20个元素;每一个元素都是一个字典;在每个字典里,键name的值,对应的是歌曲名。

3. 利用requests.get()访问这个链接,把这个字典下载到本地。然后去一层一层地读取,拿到歌曲名。

import requests

# 引用requests库

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&notice=0&platform=yqq.json&needNewCode=0')

# 调用get方法,下载这个字典

print(res.text)

我们又遇到一个障碍:使用res.text取到的,是字符串。

它不是我们想要的列表/字典,数据取不出来。

4. 新的知识点——json:

1)json是一种特殊的字符串,它是用列表/字典的语法写成的。

a='1,2,3,4'# 这是字符串

b=[1,2,3,4]# 这是列表

c='[1,2,3,4]'# 这是字符串,但它是用json格式写的字符串

2)json则是另一种组织数据的格式,长得和Python中的列表/字典非常相像。它和html一样,常用来做网络数据传输。刚刚我们在XHR里查看到的列表/字典,严格来说其实它不是列表/字典,它是json。

3)直接写成列表/字典不就好了,为什么要把它表示成字符串?答案很简单,因为不是所有的编程语言都能读懂Python里的数据类型(如,列表/字符串),但是所有的编程语言,都支持文本类型。如此,json数据才能实现,跨平台,跨语言工作。

4)json和XHR之间的关系:XHR用于传输数据,它能传输很多种数据,json是被传输的一种数据格式。就是这样而已。

5)我们总是可以将json格式的数据,转换成正常的列表/字典,也可以将列表/字典,转换成json。

6)当我们请求得到了json数据,应该如何读取呢?我们可以在requests库的官方文档中,找到答案。如果你想在Python语言中,实现列表/字典转json,json转列表/字典,则需要借助json模块。


import requests

# 引用requests库

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&notice=0&platform=yqq.json&needNewCode=0')

# 调用get方法,下载这个字典

json_music = res_music.json()

# 使用json()方法,将response对象,转为列表/字典

print(type(json_music))

# 打印json_music的数据类型

6.  编写代码爬取歌名:

import requests# 引用requests库

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&notice=0&platform=yqq.json&needNewCode=0')# 调用get方法,下载这个字典

json_music=res_music.json()# 使用json()方法,将response对象,转为列表/字典

list_music=json_music['data']['song']['list']# 一层一层地取字典,获取歌单列表

for music in list_music:# list_music是一个列表,music是它里面的元素

print(music['name'])# 以name为键,查找歌曲名

7.  编写代码爬取更多信息:

print(music['name'])# 以name为键,查找歌曲名

print('所属专辑:'+music['album']['name'])# 查找专辑名

print('播放时长:'+str(music['interval'])+'秒')# 查找播放时长

print('播放链接:https://y.qq.com/n/yqq/song/'+music['mid']+'.html\n\n')# 查找播放链接

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,362评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,330评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,247评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,560评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,580评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,569评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,929评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,587评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,840评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,596评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,678评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,366评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,945评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,929评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,165评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,271评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,403评论 2 342

推荐阅读更多精彩内容