python爬虫实例网易云-爬虫实战(二) 用Python爬取网易云歌单
最近,博主喜欢上了听歌,但是又苦于找不到好音乐,于是就打算到网易云的歌单中逛逛
本着 "用技术改变生活” 的想法,于是便想着写一个爬虫爬取网易云的歌单,并按播放量自动进行排序
这篇文章,我们就来讲讲怎样爬取网易云歌单,并将歌单按播放量进行排序,下面先上效果图
1、用 requests 爬取网易云歌单
打开 网易云音乐 歌单首页,不难发现这是一个静态网页,而且格式很有规律,爬取起来应该十分简单
按照以前的套路,很快就可以写完代码,无非就是分为下面几个部分:
(1)获取网页源代码
这里我们使用 requests 发送和接收请求,核心代码如下:
import requests
def get_page(url):
# 构造请求头部
headers = {
'USER-AGENT':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36'
}
# 发送请求,获得响应
response = requests.get(url=url,headers=headers)
# 获取响应内容
html = response.text
return html
(2)解析网页源代码
解析数据部分我们使用 xpath(对于 xpath 的语法不太熟悉的朋友,可以看看博主之前的文章)
核心代码如下:
from lxml import etree
# 解析网页源代码,获取数据
def parse4data(self,html):
html_elem = etree.HTML(html)
# 播放量
play_num = html_elem.xpath('//ul[@id="m-pl-container"]/li/div/div/span[@class="nb"]/text()')
# 歌单名称
song_title = html_elem.xpath('//ul[@id="m-pl-container"]/li/p[1]/a/@title')
# 歌单链接
song_href = html_elem.xpath('//ul[@id="m-pl-container"]/li/p[1]/a/@href')
song_link = ['https://music.163.com/#'+item for item in song_href]
# 用户名称
user_title = html_elem.xpath('//ul[@id="m-pl-container"]/li/p[2]/a/@title')
# 用户链接
user_href = html_elem.xpath('//ul[@id="m-pl-container"]/li/p[2]/a/@href')
user_link = ['https://music.163.com/#'+item for item in user_href]
# 将数据打包成列表,其中列表中的每一个元素是一个字典,每一个字典对应一份歌单信息
data = list(map(lambda a,b,c,d,e:{'播放量':a,'歌单名称':b,'歌单链接':c,'用户名称':d,'用户链接':e},play_num,song_title,song_link,user_title,user_link))
# 返回数据
return data
# 解析网页源代码,获取下一页链接
def parse4link(self,html):
html_elem = etree.HTML(html)
# 下一页链接
href = html_elem.xpath('//div[@id="m-pl-pager"]/div[@class="u-page"]/a[@class="zbtn znxt"]/@href')
# 如果为空,则返回 None;如果不为空,则返回链接地址
if not href:
return None
else:
return 'https://music.163.com/#' + href[0]
(3)完整代码
import requests
from lxml import etree
import json
import time
import random
class Netease_spider:
# 初始化数据
def __init__(self):
self.originURL = 'https://music.163.com/#/discover/playlist'
self.data = list()
# 获取网页源代码
def get_page(self,url):
headers = {
'USER-AGENT':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36'
}
response = requests.get(url=url,headers=headers)
html = response.text
return html
# 解析网页源代码,获取数据
def parse4data(self,html):
html_elem = etree.HTML(html)
play_num = html_elem.xpath('//ul[@id="m-pl-container"]/li/div/div/span[@class="nb"]/text()')
song_title = html_elem.xpath('//ul[@id="m-pl-container"]/li/p[1]/a/@title')
song_href = html_elem.xpath('//ul[@id="m-pl-container"]/li/p[1]/a/@href')
song_link = ['https://music.163.com/#'+item for item in song_href]
user_title = html_elem.xpath('//ul[@id="m-pl-container"]/li/p[2]/a/@title')
user_href = html_elem.xpath('//ul[@id="m-pl-container"]/li/p[2]/a/@href')
user_link = ['https://music.163.com/#'+item for item in user_href]
data = list(map(lambda a,b,c,d,e:{'播放量':a,'歌单名称':b,'歌单链接':c,'用户名称':d,'用户链接':e},play_num,song_title,song_link,user_title,user_link))
return data
# 解析网页源代码,获取下一页链接
def parse4link(self,html):
html_elem = etree.HTML(html)
href = html_elem.xpath('//div[@id="m-pl-pager"]/div[@class="u-page"]/a[@class="zbtn znxt"]/@href')
if not href:
return None
else:
return 'https://music.163.com/#' + href[0]
# 开始爬取网页
def crawl(self):
# 爬取数据
print('爬取数据')
html = self.get_page(self.originURL)
data = self.parse4data(html)
self.data.extend(data)
link = self.parse4link(html)
while(link):
html = self.get_page(link)
data = self.parse4data(html)
self.data.extend(data)
link = self.parse4link(html)
time.sleep(random.random())
# 处理数据,按播放量进行排序
print('处理数据')
data_after_sort = sorted(self.data,key=lambda item:int(item['播放量'].replace('万','0000')),reverse=True)
# 写入文件
print('写入文件')
with open('netease.json','w',encoding='utf-8') as f:
for item in data_after_sort:
json.dump(item,f,ensure_ascii=False)
if __name__ == '__main__':
spider = Netease_spider()
spider.crawl()
print('Finished')
2、用 selenium 爬取网易云歌单
然而,事情真的有这么简单吗?
当我们运行上面的代码的时候,会发现解析网页源代码部分,返回的竟然是空列表!
这是为什么呢?敲重点,敲重点,敲重点,这绝对是一个坑啊!
我们重新打开浏览器,认真观察网页的源代码
原来,我们所提取的元素被包含在 标签内部,这样我们是无法直接进行定位的
因为 iframe 会在原有页面中加载另外一个页面,当我们需要获取内嵌页面的元素时,需要先切换到 iframe 中
明白了原理之后,重新修改一下上面的代码
思路是利用 selenium 获取原有网页,然后使用 switch_to.frame() 方法切换到 iframe 中,最后返回内嵌网页
需要修改的地方是获取网页源代码的函数,另外也需要在初始化数据的函数中实例化 webdriver,完整代码如下:
from selenium import webdriver
from lxml import etree
import json
import time
import random
class Netease_spider:
# 初始化数据(需要修改)
def __init__(self):
# 无头启动 selenium
opt = webdriver.chrome.options.Options()
opt.set_headless()
self.browser = webdriver.Chrome(chrome_options=opt)
self.originURL = 'https://music.163.com/#/discover/playlist'
self.data = list()
# 获取网页源代码(需要修改)
def get_page(self,url):
self.browser.get(url)
self.browser.switch_to.frame('g_iframe')
html = self.browser.page_source
return html
# 解析网页源代码,获取数据
def parse4data(self,html):
html_elem = etree.HTML(html)
play_num = html_elem.xpath('//ul[@id="m-pl-container"]/li/div/div/span[@class="nb"]/text()')
song_title = html_elem.xpath('//ul[@id="m-pl-container"]/li/p[1]/a/@title')
song_href = html_elem.xpath('//ul[@id="m-pl-container"]/li/p[1]/a/@href')
song_link = ['https://music.163.com/#'+item for item in song_href]
user_title = html_elem.xpath('//ul[@id="m-pl-container"]/li/p[2]/a/@title')
user_href = html_elem.xpath('//ul[@id="m-pl-container"]/li/p[2]/a/@href')
user_link = ['https://music.163.com/#'+item for item in user_href]
data = list(map(lambda a,b,c,d,e:{'播放量':a,'歌单名称':b,'歌单链接':c,'用户名称':d,'用户链接':e},play_num,song_title,song_link,user_title,user_link))
return data
# 解析网页源代码,获取下一页链接
def parse4link(self,html):
html_elem = etree.HTML(html)
href = html_elem.xpath('//div[@id="m-pl-pager"]/div[@class="u-page"]/a[@class="zbtn znxt"]/@href')
if not href:
return None
else:
return 'https://music.163.com/#' + href[0]
# 开始爬取网页
def crawl(self):
# 爬取数据
print('爬取数据')
html = self.get_page(self.originURL)
data = self.parse4data(html)
self.data.extend(data)
link = self.parse4link(html)
while(link):
html = self.get_page(link)
data = self.parse4data(html)
self.data.extend(data)
link = self.parse4link(html)
time.sleep(random.random())
# 处理数据,按播放量进行排序
print('处理数据')
data_after_sort = sorted(self.data,key=lambda item:int(item['播放量'].replace('万','0000')),reverse=True)
# 写入文件
print('写入文件')
with open('netease.json','w',encoding='utf-8') as f:
for item in data_after_sort:
json.dump(item,f,ensure_ascii=False)
if __name__ == '__main__':
spider = Netease_spider()
spider.crawl()
print('Finished')
这样,得到目前网易云音乐中播放量排名前十的歌单如下(哈哈,又可以愉快的听歌啦):
注意:本项目代码仅作学习交流使用!!!
python爬虫实例网易云-爬虫实战(二) 用Python爬取网易云歌单相关推荐
- python爬取公交车站数据_Python爬虫实例_城市公交网络站点数据的爬取方法
爬取的站点:http://beijing.8684.cn/ (1)环境配置,直接上代码: # -*- coding: utf-8 -*- import requests ##导入requests fr ...
- python爬虫网易云音乐评论再分析_爬取网易云音乐的评论后,竟有这种发现!
原标题:爬取网易云音乐的评论后,竟有这种发现! 作者 | 志颖 责编 | 胡巍巍 用过网易云音乐听歌的朋友都知道,网易云音乐每首歌曲后面都有很多评论,热门歌曲的评论更是接近百万或者是超过百万条. 现在 ...
- python爬取网易云音乐飙升榜音乐_python爬取网易云音乐热歌榜 python爬取网易云音乐热歌榜实例代码...
想了解python爬取网易云音乐热歌榜实例代码的相关内容吗,FXL在本文为您仔细讲解python爬取网易云音乐热歌榜的相关知识和一些Code实例,欢迎阅读和指正,我们先划重点:python,网易热歌榜 ...
- python爬取网易云音乐飙升榜音乐_python爬取网易云音乐热歌榜实例代码
首先找到要下载的歌曲排行榜的链接,这里用的是: https://music.163.com/discover/toplist?id=3778678 然后更改你要保存的目录,目录要先建立好文件夹,例如我 ...
- python爬虫网易云音乐评论再分析_Scrapy爬取网易云音乐和评论(一、思路分析)...
目录: 前提: scrapy这个框架很多人用过,网上教程也很多,但大多就是爬爬小说这种比较简单且有规律的.尤其大多网站它是可以通过点击下一页的方式爬取下一页,我看到的教程也都是这样的.而网易云的按钮光 ...
- 爬虫入门经典(十) | 一文带你快速爬取网易云音乐
大家好,我是不温卜火,是一名计算机学院大数据专业大三的学生,昵称来源于成语-不温不火,本意是希望自己性情温和.作为一名互联网行业的小白,博主写博客一方面是为了记录自己的学习过程,另一方面是总结自己 ...
- python爬取音乐并保存的格式_python爬取QQ音乐歌单歌曲保存到本地,json解析
序:python强大的功能,可以爬取网上的某些信息,本次主要是通过爬歌单信息熟悉下python基础. 用到知识点: 1.python3.urllib.request.openurl 2.json (j ...
- python爬取音乐并保存_python爬取QQ音乐歌单歌曲保存到本地,json解析
序:python强大的功能,可以爬取网上的某些信息,本次主要是通过爬歌单信息熟悉下python基础. 用到知识点: 1.python3.urllib.request.openurl 2.json (j ...
- 用python爬取音乐APP歌单
这篇文章,我们就来讲讲怎样爬取歌单,并且播放量从高到低排列,下面是爬取结果 一 核心代码如下 1.需要导入的包有 from urllib import parse from lxml import e ...
- python爬取网易云音乐飙升榜音乐_python爬取网易云音乐热歌榜单(获取iframe中数据,src为空)...
一.分析思路 网易云音乐热歌榜的页面采用嵌入内联框架的方式,若爬虫直接从官网入口进入访问热歌榜 http://music.163.com/#/discover/toplist?id=3778678,是 ...
最新文章
- oracle 日期排序_日期居然用字符串保存?我笑了
- 【算法系列之十三】二叉树两叶节点的最大距离
- 笨方法“学习python笔记之循环
- #苹果maccmsv10# redis memcached 缓存的若干问题解决
- java线程同步例子_JAVA线程同步实例教程
- Java一亿电话号码去重_如何在有限的内存限制下实现数十亿级手机号码去重
- labview的RS232驱动程序
- android 直播 app下载地址,朵朵直播app下载地址
- 饥荒怎么把离线服务器改成在线,饥荒联机版专服简易启动教程
- [Luogu4173/BZOJ4259] 残缺的字符串
- 分数阶麻雀搜索算法-附代码
- 【踩坑系列】SpringBoot 项目更换浏览器选项卡的图标
- 程序员客栈V4.24版本:设置主页访问密码
- 后端编译与优化(JIT,即时编译器)
- pads-logic
- 【随笔】7月休假:粤港澳大湾区旅程记录
- SAP QM 检验点 (Inspection Point) 的使用
- [jzoj 3461]【NOIP2013模拟联考5】小麦亩产一千八 {Fibonacci数列}
- c语言中if(a字节4),【鲁班】的意思是什么?【鲁班】是什么意思?
- 搜狗输入法词库php词库怎么用,中州韵输入法导入搜狗词库(示例代码)
热门文章
- jQuery JSON jPlayer实现QQ空间音乐查询
- java supplier接口_Java函数式接口Supplier接口实例详解
- html代码房地产,HTML白色宽屏形式房地产动态网页模板代码
- RNA 27 SCI文章中转录因子结合motif富集到调控网络 (RcisTarget)
- Halcon与C#混合编程--打开笔记本摄像头实时采集
- 日语考级N1~N5各等级证书含金量如何,代表什么水平?有没有必要考?
- L1-040 最佳情侣身高差 - java
- Luogu 1315 【NOIP2011】观光公交 (贪心)
- 转一次排障经历以供学习
- 关于DIN 5510-2德国轨道车辆防火测试标准