美文网首页
07 爬取日本网站Hurtrecord的音乐下载链接

07 爬取日本网站Hurtrecord的音乐下载链接

作者: 夏威夷的芒果 | 来源:发表于2018-08-14 18:08 被阅读51次

网址

http://www.hurtrecord.com/bgm/theme.html

分析

每个主题下面有很多小类


网站样式

点开小类是下载链接:


小类里面的音乐,下载箭头背后就是链接

怎样把小类归类?

小类在主题下面,但是获取小类的时候又不能直接获取主题,因为二者样式不一样, 这里我推荐把网页的源代码字符串化,然后小类的样式和主题位置的样式也字符串化,这样使用字符串中的index方法就可以获取在网页中的相对位置了,最起码做个比较是没有问题的。可以得到数据帧。需要的帧形式:主题,小类,小类链接

怎样把小类下面的音乐拿出来并且和小类关联?

现在要根据小类的链接去打开页面挖掘歌曲,要返回歌曲名称和下砸地址的列表。
这里我是每次打来小类页面生成列表时候,转化成pandas的数据帧对象,然后统一添加小类的名称。构建列表:小类名,歌名,歌名链接

merge方法合并主键和外键。
pd.merge(catalog_df, song_df, on='小类') 笛卡尔积,当两个表连接时,有相同的key值就产生积。

代码

#爬取这个日本音乐网站的所有下载直链
import requests,os
from bs4 import BeautifulSoup
import pandas as pd
import numpy as np
from matplotlib.font_manager import FontProperties
import matplotlib.pyplot as plt

music_path = './music_link_output'  #输出的文件夹

if not os.path.exists(music_path):
    os.makedirs(music_path)

url = 'http://www.hurtrecord.com/bgm/theme.html' #一个日本网站的音乐

def get_url(url):
    music_list = []
    theme_list = []
    web_data = requests.get(url)
    soup = BeautifulSoup(web_data.content.decode('utf-8'), 'lxml')
    strsoup = str(soup)
    for theme in soup.select('#cont > h2.sube'):
        theme_txt = theme.text
        if '/' in theme_txt:
            theme_txt = ''.join(theme_txt.split('/'))
        theme_pos = strsoup.index(str(theme))
        theme_list.append([''.join(theme_txt.split()),theme_pos])   #主题,大类位置
    print(theme_list)

    items = soup.select('#cont > div > a')
    for item in items:
        item_txt = str(item)
        if 'border' not in  item_txt:
            title = str(item).split('▷ ')[1].split('</a')[0]
            href = item['href']
            item_pos = strsoup.index(str(item))
            music_list.append([title,item_pos,href])   #小类名、小类位置、小类链接
    return theme_list, music_list
#需要的帧形式: 大类,小类,小类链接



def get_music_link(url):
    # 样式 #table-010 > tbody > tr > td:nth-child(5) > a
    url = 'http://www.hurtrecord.com/bgm/84/'
    web_data = requests.get(url)
    soup = BeautifulSoup(web_data.content.decode('utf-8'), 'lxml')
    music_link_list = []
    for item in soup.select('#table-010 > tbody > tr'):  # 使用p:nth-of-type(这里写子的序数)也可以
        if '<th>No.</th>' not in str(item):
            music_link_list.append(
                [list(item)[1].text, str(list(item)[4]).split('<td><a href="')[1].split('" onclick')[0]]
            )
    return music_link_list


theme_list, music_list = get_url(url)
theme_list = [[each_theme[0] for each_theme in theme_list],[each_theme[1] for each_theme in theme_list]]

catalog = {'小类': [each_cata[0] for each_cata in music_list],
        '小类位置': [each_cata[1] for each_cata in music_list],
        '小类链接': [each_cata[2] for each_cata in music_list]}
catalog_df = pd.DataFrame(catalog)
catalog_df.insert(0,'主题',pd.cut(catalog['小类位置'],bins =  theme_list[1] + [np.inf],labels = theme_list[0]))


for my_index in catalog_df.index:  #每一行 有主题,小类,小类的链接。现在要根据小类的链接去搜索歌曲,要返回歌曲
    this_catalog = catalog_df.loc[my_index]
    this_catalog_name = this_catalog['小类']
    print(f"正在抓取{this_catalog['主题']}中的{this_catalog_name}")
    songs = get_music_link(this_catalog['小类链接'])   #列表,元素是歌名+链接
    #构建列表:小类名,歌名,歌名链接
    this_songs_df =  pd.DataFrame({'小类':[this_catalog_name]*len(songs),
                                   '曲名': [song[0] for song in songs],
                                   '下载地址':[song[1] for song in songs]
                                   })
    song_df = this_songs_df if my_index == 0 else pd.concat([song_df,this_songs_df])


data = pd.merge(catalog_df, song_df, on='小类')  #笛卡尔积,当两个表连接时,有相同的key值就产生积。
data.drop(['小类链接','小类位置'], inplace=True)
data.to_csv(os.path.join(music_path,'Japanese_Music.csv'), index = False) #其实默认是带索引保存的,这里不该带索引。


data = pd.read_csv('/Users/miraco/PycharmProjects/grabnet/music_link_output/Japanese_Music.csv')
x = [0]
#data.drop(data.columns[x], axis=1, inplace=True) #其实删除第0列,索引列,如果当初选择了带索引保存
count_df = data.groupby('主题').count()['曲名']


count_df.plot(kind = 'bar',stacked  = True)

plt.title(u'歌曲统计', fontsize=18, fontproperties=FontProperties(fname='/System/Library/Fonts/PingFang.ttc'))
plt.xticks(fontproperties=FontProperties(fname='/System/Library/Fonts/PingFang.ttc'),rotation =30)
plt.yticks(fontproperties=FontProperties(fname='/System/Library/Fonts/PingFang.ttc'))
plt.xlabel('主题',fontproperties=FontProperties(fname='/System/Library/Fonts/PingFang.ttc'))
plt.ylabel('曲数目',fontproperties=FontProperties(fname='/System/Library/Fonts/PingFang.ttc'))
#plt.legend(prop = FontProperties(fname='/System/Library/Fonts/PingFang.ttc'))

plt.tight_layout()
plt.show()

运行结果:

统计 表格
表格

其实如果想要下载的话也是可以的:

但是我没什么精力去弄这个了,举个例子。

import requests

url = 'http://www.hurtrecord.com/bgm/67/shizukesa-no-ato.mp3'
music = requests.get(url)

with open('music.mp3','wb') as f:
    f.write(music.content)

踩过的坑

import pandas as pd
import numpy as np
df = pd.DataFrame(np.arange(12).reshape(3,4),
                      columns=['A', 'B', 'C', 'D'])

x=[1,2]
df.drop(df.columns[x], axis=1, inplace=True)
print df

相关文章

网友评论

      本文标题:07 爬取日本网站Hurtrecord的音乐下载链接

      本文链接:https://www.haomeiwen.com/subject/itnvbftx.html