Python爬虫网易云歌词及词频统计

0

采用词云对邓紫棋的热门前50歌曲进行可视化展示。

本次可视化步骤需要掌握的内容有:

  1. 了解爬虫的原理
  2. 掌握xpath的用法
  3. 掌握词云工具wordcloud的使用
  4. 了解分词根据jieba的使用
  5. 正则表达式的复习

首先,需要找到网易云音乐的音乐人的网页链接,再根据热门歌曲获取每一首热门歌曲的歌词。

获取每首歌的歌曲ID,歌曲名称
获取每首歌的歌词,汇总成一个歌词文本
创建词云模型,进行展示。
本文可参考:https://blog.csdn.net/weixin_...

下面是一些进行项目时候的一些小错误,直接用pycharm的debug功能仔细查看哪一个步骤出错了,需要细心去写代码,爬虫很容易出现一些非语法方面的错误。
非语法错误

获取指定歌手页面的xpath的时候,少打了一个@ ,导致没有获取到相应歌曲的网页链接的ID。
图片描述

获取网易云音乐歌词的时候,打错了关键字,将歌词 'lrc'错打成了 'lyc',导致没有歌词输出,同时正则表达式少打了一个 ]

# -*- coding:utf-8 -*-
# 网易云音乐 通过歌手ID,生成该歌手的词云
import requests
import os
import re
import sys
from wordcloud import WordCloud
import matplotlib.pyplot as plt
from PIL import Image
import numpy as np
import jieba
from lxml import etree


headers = {
    'Referer': 'http://music.163.com',
    'Host': 'music.163.com',
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
    'User-Agent': 'Chrome/10'
}
# 得到某首歌的歌词
def get_song_lyric(headers,lyric_url):
    res = requests.request('GET',lyric_url,headers=headers)
    if 'lrc' in res.json():
        # lyric = res.json()['lyc']['lyric'] # 根据页面获取歌词文件
        lyric = res.json()['lrc']['lyric']  # 根据页面获取歌词文件
        # new_lyric = re.sub(r'[\d:.[\]','',lyric) # 对歌词里面的时间等进行正则表达式替换
        new_lyric = re.sub(r'[\d:.[\]]','', lyric)  # 对歌词里面的时间等进行正则表达式替换
        return new_lyric
    else:
        return ''
        # print(res.json())


# 去掉停用词
def remove_stop_words(f):
    stop_words = ['作词', '作曲', '编曲', 'Arranger', '录音', '混音', '人声', 'Vocal', '弦乐', 'Keyboard', '键盘', '编辑', '助理',
                  'Assistants', 'Mixing', 'Editing', 'Recording', '音乐', '制作', 'Producer', '发行', 'produced', 'and',
                  'distributed']
    for stop_word in stop_words:
        f = f.replace(stop_word,"")
    return f


# 得到指定歌手页面 热门前50的歌曲ID,歌曲名
def get_songs(artist_id):
    page_url = 'https://music.163.com/artist?id=' + artist_id
    # 获取网页 HTML
    res = requests.request('GET',page_url,headers=headers)
    # 用xpath 解析热门前50的歌曲信息
    html = etree.HTML(res.text)
    href_xpath = "//*[@id='hotsong-list']//a/@href"
    name_xpath = "//*[@id='hotsong-list']//a/text()"
    # href_xpath = "//*[@id='hotsong-list']//a/@href"
    # name_xpath = "//*[@id='hotsong-list']//a/text()"
    hrefs = html.xpath(href_xpath)
    names = html.xpath(name_xpath)
    # 设置热门歌曲的ID,歌曲名称
    song_ids = []
    song_names = []
    for href,name in zip(hrefs,names):
        song_ids.append(href[9:])
        song_names.append(name)
        print(href,' ',name)
    return song_ids,song_names


# 生成词云
def creat_word_cloud(f):
    print("根据词频,开始生成词云!")
    f = remove_stop_words(f)
    cut_text = " ".join(jieba.cut(f,cut_all=False,HMM=True))
    wc = WordCloud(
        font_path="./wc.ttf",
        max_words=100,
        width = 2000,
        height = 1200,
    )
    print(cut_text)
    wordcloud = wc.generate(cut_text)
    # 写词云文件
    wordcloud.to_file("artist_wordcloud.jpg")
    # 展示词云文件
    plt.imshow(wordcloud)
    plt.axis("off")
    plt.show()


# 设置歌手 ID,邓紫棋为 7763
artist_id = '7763'
[song_ids,song_names] = get_songs(artist_id)
# 所有歌词
all_words = ''
# 获取每首歌歌词
for (song_id,song_name) in zip(song_ids,song_names):
    # 歌词api url
    lybric_url = 'http://music.163.com/api/song/lyric?os=pc&id=' + song_id + '&lv=-1&kv=-1&tv=-1'
    lyric = get_song_lyric(headers,lybric_url)
    all_words = all_words + " " + lyric
    print(song_name)


# 根据词频生成词云
creat_word_cloud(all_words)

你可能感兴趣的

载入中...