python爬取网易云音乐热歌榜单(获取iframe中数据,src为空)

一.分析思路

网易云音乐热歌榜 的页面采用嵌入内联框架的方式,若爬虫直接从官网入口进入访问热歌榜
http://music.163.com/#/discover/toplist?id=3778678 ,是无法获取到iframe框架内的数据的,因此应当用另外的方法进行访问。当然最简单的方法可以用selenium+chrome的方式进行获取数据(使用switch_to.frame方法,网上有很多教程)。

第二种方法采用分析api的方式进行,内嵌的框架实际上也是一个网页资源,因此只要我们找到它的链接,然后获取到这一页面,自然也能获取到数据。本文采取此方式进行分析和编写程序。

二.分析需求

获取热歌榜上所有歌曲名称,以及歌手,歌曲时长,专辑等信息。

三.使用chrome开发工具分析页面

1.打开 网易云音乐热歌榜 页面,按下F12,打开chrome的开发者工具,找到iframe元素,发现其src为空,并且可以看到iframe中的内容是使用javascript生成的:
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'--------------------------------------------------------------------'

输出结果: