《中国有嘻哈》这款综艺带火了中国的嘻哈音乐,大家问好也都变成了:你有freestyle吗?

相信大家都是因为这篇高大上的微信推送文章来的。

没看到也不要紧,传送带在这里–>爱票子也爱妹子:300万字歌词分析看中国rapper到底在唱什么。

真心觉得寒小阳老师的数据分析技术很厉害~还有小编的文笔也很赞~

我主要负责了数据采集的部分。通俗点就是编写一个爬虫,把大量歌曲歌词爬下来。

点击右侧链接,可访问源码资源:网易云、虾米音乐歌词爬虫源码

确定爬取目标

网易云音乐中国嘻哈榜-主播电台 吸引了我们的注意。这是最贴近《中国有嘻哈》这个热点的。随着综艺的播出,每周都有新的节目歌曲更新。现在已经到372期了。

首先可以看到节目列表。

点击“节目”进入另一个页面:歌曲列表。发现这期节目有10首歌。

点击“歌曲”进入歌曲主页,发现了我们想要的歌词,眼前一亮~

“展开”这个刺眼的js标签让歌词内容部分遮掩。

我们不得不来个selenium模拟鼠标点击,才能得到想要的歌词吗?

其实不必这样,细心的组长早就发现了简单的方法:

取得节目列表下所有歌曲信息

提示:歌词 -> 使用 http://music.163.com/api/song/media?id=421203370(歌曲编号)来取得。

当时电台也已经更新了208期了,如果每期有10首的,将会得到约2000首歌。

后来,将全部数据爬下来才证明是too naive 了。歌曲重复实在是太多,去重之后,发现才368首,368首!

痛定思痛,我们把目光瞄向了虾米音乐。在搜索框中输下”hip-hop”,

回车,我们发现虾米音乐可以搜索特定标签的歌曲,就比如hip-hop。

往后翻页,总共有401页。而且url很有规律,可以直接访问。这个好。

偷偷估算了一下,401页,每页30首,可以得到1万两千首,amazing!

不过这次,首先爬取了url,并进行筛重。最后,剩余能有五六千首的样子。

它—虾米,歌词的页面。

好了,爬取目标已确定。

编写爬虫

看一下代码。

使用的是scrapy爬虫框架,很灵活很强大。

与正则表达式、beautifulsoup库相比,有很方便的自定义配置和定制。

在这个框架中,工作主要集中在

  • items
  • spiders

可能还会用到

  • pipelines
  • middlewares

还有一个配置文件

  • settings

网易云音乐爬虫代码

  • items.py
# -*- coding: utf-8 -*-# Define here the models for your scraped items
#
# See documentation in:
# http://doc.scrapy.org/en/latest/topics/items.htmlimport scrapyclass ProgramItem(scrapy.Item):# define the fields for your item here like:# name = scrapy.Field()program_url=scrapy.Field() #节目链接issue=scrapy.Field() #期号create_time=scrapy.Field() #创建时间play_times=scrapy.Field() #播放次数subscription_number=scrapy.Field() #订阅次数like_number=scrapy.Field() #点赞数comment_number=scrapy.Field() #评论数share_number=scrapy.Field() #分享数class SongItem(scrapy.Item):song_id=scrapy.Field() #歌曲编号artist_id=scrapy.Field() #歌手编号album_id=scrapy.Field() #所属专辑编号comment_number=scrapy.Field() #评论数title=scrapy.Field() #歌曲名class LyricItem(scrapy.Item):song_id=scrapy.Field() #歌曲编号lyric=scrapy.Field() #歌词
  • middlewares.py
# -*- coding: utf-8 -*-# Define here the models for your spider middleware
#
# See documentation in:
# http://doc.scrapy.org/en/latest/topics/spider-middleware.htmlfrom scrapy import signals
from scrapy.http import HtmlResponse
from lxml import etree
import time
from random import choice
from selenium import webdriver
from selenium.webdriver.common.desired_capabilities import DesiredCapabilitiesua_list = ["Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/48.0.2564.82 Chrome/48.0.2564.82 Safari/537.36","Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36","Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.93 Safari/537.36","Mozilla/5.0 (X11; OpenBSD i386) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.125 Safari/537.36","Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1664.3 Safari/537.36"
]
dcap = dict(DesiredCapabilities.PHANTOMJS)
dcap["phantomjs.page.settings.resourceTimeout"] = 15
dcap["phantomjs.page.settings.loadImages"] = False
dcap["phantomjs.page.settings.userAgent"] = choice(ua_list)class Music163XihaSpiderMiddleware(object):# Not all methods need to be defined. If a method is not defined,# scrapy acts as if the spider middleware does not modify the# passed objects.sleep_seconds = 0.2  # 模拟点击后休眠3秒,给出浏览器取得响应内容的时间default_sleep_seconds = 1  # 无动作请求休眠的时间def process_request(self, request, spider):spider.logger.info('--------Spider request processed: %s' % spider.name)page = Noneif 'djradio' in request.url or 'program' in request.url or 'song?id=' in request.url:driver = webdriver.PhantomJS()spider.logger.info('--------request.url: %s' % request.url)driver.get(request.url)driver.implicitly_wait(1)# 仅休眠数秒加载页面后返回内容time.sleep(self.sleep_seconds)driver.switch_to.frame(driver.find_element_by_name("contentFrame")) # 取得框架内容page = driver.page_sourcedriver.close()elif 'media' in request.url:driver = webdriver.PhantomJS()spider.logger.info('--------request.url: %s' % request.url)driver.get(request.url)driver.implicitly_wait(0.2)# 仅休眠数秒加载页面后返回内容time.sleep(self.sleep_seconds)page = driver.page_sourcedriver.close()return HtmlResponse(request.url, body=page, encoding='utf-8', request=request)
  • spiders.py
#-*- coding: utf-8 -*-import scrapy
import os, json, codecs
from hashlib import md5
from faker import Factory
from music163xiha.items import LyricItemf = Factory.create()'''
取得节目列表下所有歌曲信息提示:歌词 -> 使用 http://music.163.com/api/song/media?id=421203370(歌曲编号)来取得cd /home/andy/000_music163xiha/scrapy/music163xiha/spiders
pyenv activate scrapy2.7
scrapy crawl songs'''
class LyricsSpider(scrapy.Spider):lyric_url = 'http://music.163.com/api/song/media?id='song_list_file='./result/song_url.txt'name = "lyrics"allowed_domains = ["music.163.com"]def __init__(self, *args, **kwargs):#从上一步骤取得的 song_list 文件中读取得到所有 urlf = open(self.song_list_file,"r") lines = f.readlines()if len(lines)==0:self.log('*************\nPlease run spider \'programs\' first\nto get program_url.txt\n****************')print '************'print len(lines)print '************'song_id_list=[line.split('=')[1] for line in lines]song_list=[self.lyric_url+song_id for song_id in song_id_list]f.close()print '************'print song_list[0]print '************'self.start_urls = song_list # 此处应从上一步骤取得的 program_list 文件中读取得到所有 urldef parse(self, response):self.log('--> url:%s' % response.url)result = response.xpath('//body/text()').extract_first()json_result = json.loads(result, encoding='utf-8')#self.log('--> lyric:%s' % json_result['lyric'])lyric_text=json_result['lyric']#歌词lyric=LyricItem()lyric['lyric']=lyric_textlyric['song_id']=response.url.split('=')[1][:-3]#因为‘=’后面的id后面莫名其妙的跟着3个字母%0A,遂去掉,加[:-3]yield lyric

虾米音乐爬虫代码

  • items.py
# -*- coding: utf-8 -*-# Define here the models for your scraped items
#
# See documentation in:
# http://doc.scrapy.org/en/latest/topics/items.htmlimport scrapyclass SongUrlItem(scrapy.Item):# define the fields for your item here like:# name = scrapy.Field()song_url=scrapy.Field() #歌曲链接class LyricItem(scrapy.Item):# define the fields for your item here like:# name = scrapy.Field()lyric=scrapy.Field() #歌曲链接song_url=scrapy.Field() #歌曲链接class SongInfoItem(scrapy.Item):# define the fields for your item here like:# name = scrapy.Field()song_url=scrapy.Field() #歌曲链接song_title=scrapy.Field() #歌名album=scrapy.Field() #专辑#singer=scrapy.Field() #歌手language=scrapy.Field() #语种
  • spider.py
# -*- coding: utf-8 -*-
import scrapy
from xiami.items import LyricItemclass LyricsSpider(scrapy.Spider):name='Lyrics'allowed_domains=['xiami.com']song_url_file='./result/song_url.csv'def __init__(self, *args, **kwargs):#从song_url.csv 文件中读取得到所有歌曲urlf = open(self.song_url_file,"r") lines = f.readlines()#这里line[:-1]的含义是每行末尾都是一个换行符,要去掉#这里in lines[1:]的含义是csv第一行是字段名称,要去掉song_url_list=[line[:-1] for line in lines[1:]]f.close()self.start_urls = song_url_list#[:100]#删除[:100]之后爬取全部数据def parse(self,response):lyric_lines=response.xpath('//*[@id="lrc"]/div[1]/text()').extract()lyric=''for lyric_line in lyric_lines:lyric+=lyric_line#print lyriclyricItem=LyricItem()lyricItem['lyric']=lyriclyricItem['song_url']=response.urlyield lyricItem

完整代码稍后会更新到我的github。

遇到的困难和问题解决

  • 爬虫访问太快,被服务器拒绝访问

可以在settings.py设置:

DOWNLOAD_DELAY=1

还有其它防止被拒绝访问的措施:

设置用户代理

from faker import Factory
f = Factory.create()
USER_AGENT = f.user_agent()

设置请求头

# Override the default request headers:
DEFAULT_REQUEST_HEADERS = {'Host': 'www.xiami.com','Accept': '*/*','Accept-Encoding': 'gzip, deflate, br','Accept-Language': 'zh-CN,zh;q=0.8','Cache-Control': 'no-cache','Connection': 'Keep-Alive',
}
  • xpath爬不到

比如Chrome浏览器会对一些html源码进行规范。有的时候右键“检查”得到的xpath路径是错误的。比如tbody这个标签。

  • 网易云音乐有些页面使用了一种叫做iframe 的结构。

抓取其中内容需要,在中间件中做一些工作。

    def process_request(self, request, spider):spider.logger.info('--------Spider request processed: %s' % spider.name)page = Noneif 'djradio' in request.url or 'program' in request.url or 'song?id=' in request.url:driver = webdriver.PhantomJS()spider.logger.info('--------request.url: %s' % request.url)driver.get(request.url)driver.implicitly_wait(1)# 仅休眠数秒加载页面后返回内容time.sleep(self.sleep_seconds)driver.switch_to.frame(driver.find_element_by_name("contentFrame")) # 取得框架内容page = driver.page_sourcedriver.close()elif 'media' in request.url:driver = webdriver.PhantomJS()spider.logger.info('--------request.url: %s' % request.url)driver.get(request.url)driver.implicitly_wait(0.2)# 仅休眠数秒加载页面后返回内容time.sleep(self.sleep_seconds)page = driver.page_sourcedriver.close()return HtmlResponse(request.url, body=page, encoding='utf-8', request=request)

中国有嘻哈:网易云、虾米音乐歌词爬虫项目分享相关推荐

  1. 网易云修改音乐名字(不能是在线的)

    网易云修改音乐名字(不能是在线的) 技术小白,先水一篇 打开本地音乐文件所在的目录 打开文件属性中的详细信息 修改标题和备注,改成你想的名字就好了 PS这是我才知道的,但是看见有人发修改格式的,所以就 ...

  2. 后版权时代——为什么我不看好网易云的音乐社区,而看好腾讯的长音频?

    文|编程浪子 来源|螳螂财经(ID:TanglangFin) "想听周杰伦,那您还是得上QQ音乐",螳螂财经编辑组的资深周杰伦铁粉 @行川 这样告诉笔者. 业界公认,QQ音乐在热点 ...

  3. 网易云放音乐加载不出来 CSDN打不开等问题 重新分配IP地址

    网易云放音乐加载不出来 CSDN打不开等问题 重新分配一个ip地址 方法一: windows+r 打开cmd 输入 ipconfig /release 重新连一遍网 方法二: 百度网盘下载下面cmd文 ...

  4. Vue2仿网易云风格音乐播放器(附源码)

    Vue2仿网易云风格音乐播放器 1.整体效果 2.使用技术 3.实现内容 4.源码 5.使用图片 1.整体效果 2.使用技术 使用了HTML5 + CSS3进行页面布局及美化 使用Vue2进行数据渲染 ...

  5. java怎么爬网易云_Python爬虫爬取网易云的音乐

    Python爬虫爬取网易云的音乐(学习笔记) 在开始之前,做一点小小的说明哈: 我只是一个python爬虫爱好者,如果本文有侵权,请联系我删除! 本文需要有简单的python爬虫基础,主要用到两个爬虫 ...

  6. 如何阻止网易云等音乐软件删歌

    实现阻止网易云等音乐软件删歌:通过限制文件夹的删除权限就可以实现 1.右键文件夹选择属性,点击编辑 2.添加权限 4.修改为特殊权限 6.成功后的测试:可以添加文件,也可以打开文件,但是在删除时需要授 ...

  7. 网易云VIP音乐NCM文件转MP3,C语言版本

    前言 网易云的Vip音乐下载下来,格式不是mp3/flac这种通用的音乐格式,而是经过加密的ncm文件.只有用网易云的音乐App才能够打开.于是想到可不可以把.ncm文件转换成mp3或者flac文件, ...

  8. 图虫网、人人字幕Scrapy爬虫实战分享 附源码

    图虫网.人人字幕Scrapy爬虫实战分享 文章已发表在个人博客,欢迎点击这里访问 序 最近用Scrapy爬取了图虫和人人字幕,图虫网以前是纯摄影爱好论坛,现在往图库方向发展了,图片质量上佳,人人字幕也 ...

  9. 如何在HTML页面中引入一首网易云音乐以及B站的视频

    偶然发现的一些有趣的玩意,话不多说,直接上代码. 由于CSDN不支持直接渲染HTML,具体可以查看:浓烟下与荒野 一.网易云音乐 <div style="text-align:cent ...

最新文章

  1. 2021-2027年中国智能马桶盖行业市场研究及前瞻分析报告
  2. 【深度学习】(7) 交叉验证、正则化,自定义网络案例:图片分类,附python完整代码
  3. 云计算服务在小企业中的作用?
  4. 开发日记-20190405
  5. php stream 函数集
  6. IP插件:批量替换论文图片
  7. C++vigenere cipher维吉尼亚密码算法(附完整源码)
  8. 教程:创建简单的 ETL 包
  9. 第二百七十九节,MySQL数据库-pymysql模块操作数据库
  10. 工作中,我们经常用到哪些SQL语句呢?
  11. wifi不断重连报错:eSIR_MAC_CLASS3_FRAME_FROM_NON_ASSOC_STA_REASON解决
  12. [Selenium]怎样验证页面是否有无变化
  13. 算法竞赛入门经典 aabb
  14. DataParallel使用
  15. c语言yuv图片cb,YUV格式图像基础
  16. 五金行业智慧采购解决方案:应用集中采购协同管理系统激活企业数字化采购价值
  17. 微信小程序swiper组件切换+个人资料展示
  18. 偏振成像的基本原理和特点
  19. MTK android 可修改IMEI方法
  20. 区块链技术3--BTC协议

热门文章

  1. 大鱼号自媒体如何快速通过试运营转正?
  2. aspen压缩因子_Aspen物性参数中英文对照
  3. MySql的详细安装与配置步骤
  4. 产品经理——从一块钱看产品推广方案
  5. 手zhuan手机软件app下载排行网站源码(需要自取)
  6. day05【JQuery框架】HTML引入Jquery、jQuery与JS区别、基本选择器、层级关系选择器、属性选择器、过滤选择器、 对象遍历、Jquery的DOM操作【重点】、Jquery事件绑定
  7. 令克软件再推OpenAPI与MAS系统服务,强大引擎赋能券商多元化发展
  8. KVM基于Web部署虚拟主机
  9. R语言中的并行计算实现
  10. Linux下文件备份和同步的工具软件