一.分析思路
网易云音乐热歌榜的页面采用嵌入内联框架的方式,若爬虫直接从官网入口进入访问热歌榜
http://music.163.com/#/discover/toplist?id=3778678,是无法获取到iframe框架内的数据的,因此应当用另外的方法进行访问。当然最简单的方法可以用selenium+chrome的方式进行获取数据(使用switch_to.frame方法,网上有很多教程)。
第二种方法采用分析api的方式进行,内嵌的框架实际上也是一个网页资源,因此只要我们找到它的链接,然后获取到这一页面,自然也能获取到数据。本文采取此方式进行分析和编写程序。
二.分析需求
获取热歌榜上所有歌曲名称,以及歌手,歌曲时长,专辑等信息。
三.使用chrome开发工具分析页面
1.打开网易云音乐热歌榜页面,按下F12,打开chrome的开发者工具,找到iframe元素,发现其src为空,并且可以看到iframe中的内容是使用javascript生成的:
2.因此我们需要分析api找到我们所需的链接。再选择network,选择Doc,然后重新加载界面,发现文件有两个:
3.分别在这两文件的response中搜索榜单上的任意一首歌,发现榜单在第二个document中:
4.右键这一Doc,选择copy/copy link address获取内嵌框架的链接。
5.用此链接另外打开一个界面发现界面又跳回原来的页面,因此我们在原来的网页右击选择查看框架源代码,搜索后发现榜单数据是以json的格式存在<textarea>这一标签下:
6.我们采用chrome扩展插件json handle来分析这些json数据:
这样就获取到我们想要的数据了
四.编写程序
代码如下:
#—*—coding=utf-8
import requests
import sys
import json
import time
reload(sys)
sys.setdefaultencoding('utf8')
from bs4 import BeautifulSoup
url1 = 'http://music.163.com/discover/toplist?id=3778678'#云音乐热歌榜
#UA必須要設置,未设置获取的网页不完整
headers = {
'Cookie':'__e_=1515461191756; _ntes_nnid=af802a7dd2cafc9fef605185da6e73fb,1515461190617; _ntes_nuid=af802a7dd2cafc9fef605185da6e73fb; JSESSIONID-WYYY=HMyeRdf98eDm%2Bi%5CRnK9iB%5ChcSODhA%2Bh4jx5t3z20hhwTRsOCWhBS5Cpn%2B5j%5CVfMIu0i4bQY9sky%5CsvMmHhuwud2cDNbFRD%2FHhWHE61VhovnFrKWXfDAp%5CqO%2B6cEc%2B%2BIXGz83mwrGS78Goo%2BWgsyJb37Oaqr0IehSp288xn5DhgC3Cobe%3A1515585307035; _iuqxldmzr_=32; __utma=94650624.61181594.1515583507.1515583507.1515583507.1; __utmc=94650624; __utmz=94650624.1515583507.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); __utmb=94650624.4.10.1515583507',
'Host':'music.163.com',
'Refere':'http://music.163.com/',
'Upgrade-Insecure-Requests':'1',
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'
}
response = requests.get(url1,headers=headers)
print response.status_code
html = response.text
soup = BeautifulSoup(html,'lxml')
update_time = soup.find('span',attrs={'class':'sep s-fc3'}).text
print update_time
#找到json数据
textarea = soup.find('textarea').text
i = 1
contents = json.loads(str(textarea))
#将数据输出到wangyi.log文件中
fo = open('wangyi.log','w')
sys.stdout = fo
for a in range(len(contents)):
#发行时间
t1 = time.localtime(contents[a].get('publishTime')/1000)
t2 = time.strftime("%Y-%m-%d %H:%M:%S",t1)
#歌曲时长
t3 = contents[a].get('duration')/1000
min = str(t3/60)
sec = str(t3%60)
if len(sec)<2:
sec = '0'+str(sec)
#歌手
artist = contents[a].get('artists')[0].get('name')
#歌名
music_name = contents[a].get('name')
#专辑
album = contents[a].get('album').get('name')
print i,'.',music_name,u' 播放时长:',min+':'+str(sec)#.encode('gbk','ignore')
print u'歌手:',artist
print u'专辑:',album
#其他信息
if contents[a].get('alias'):
alias = contents[a].get('alias')[0]
print alias
print u'发行时间:',t2
i += 1
print'--------------------------------------------------------------------'
输出结果: