はなたの日記

プログラミングとギターのコードについて書きます

歌詞サイトのアクセス数からflumpoolの人気曲を調べてみた(スクレイピング編)

スクレイピングの練習。
今回は、flumpoolの人気曲を歌詞サイトのアクセス数から割り出してみました。
利用したサイトはこちら↓
www.uta-net.com

「人気順でソートできるから、それ見りゃええやん」っていうツッコミはなしでお願いします。
スクレイピングで①曲名②アクセス数③発売してからの経過日数を抽出して、csvを作成します。
例:「証,123456,365」みたいな感じです。
データ取得日:2019/01/14
曲数:101

コード

# 必要なライブラリのimport
import requests
from bs4 import BeautifulSoup
from datetime import datetime
import csv
from tqdm import tqdm
import urllib.request
import glob
import time
import os


# グローバル変数
html_save_dir = './html/'
csv_save_dir = './csv/'


def get_url(soup):
    base_url = 'https://www.uta-net.com'
    id_url = soup.a.get('href')
    song_url = base_url + id_url
    return song_url


def get_access_num(soup):
    access_num_str = soup.find('div', class_='access_count').span.string  # アクセス数を文字列で取得
    access_num = int(access_num_str.replace(',', ''))  # 1,234を1234へ変換
    return access_num


def get_period(soup):
    date_original = soup.find('div', id='view_amazon').text  # 発売日:2015-01-01商品番号…
    date_str = date_original.split('商')[0].split(':')[-1]  # '商'で区切った後、':'で区切って日付のみ抽出
    date = datetime.strptime(date_str, '%Y-%m-%d')  # 日付型に変換
    today = datetime.today()
    period = (today - date).days
    return period


def crawling():
    # 曲一覧ページをsoupへ
    url = 'https://www.uta-net.com/search/?Keyword=flumpool&x=0&y=0&Aselect=1&Bselect=3'
    html = requests.get(url)
    soup = BeautifulSoup(html.content, 'html.parser')

    # 全曲取得
    songs_soup_lst = soup.find_all('td', class_='side td1')

    print('クローリング開始')
    os.makedirs(html_save_dir,exist_ok=True) # html保存場所作成

    # 各曲htmlのダウンロード
    for idx, song_soup in enumerate(tqdm(songs_soup_lst)):
        song_name = song_soup.a.string
        song_url = get_url(song_soup)
        html_name = '{0}_{1}.html'.format(idx, song_name)
        urllib.request.urlretrieve(song_url, html_save_dir + html_name) # ダウンロード
        time.sleep(1) # 間隔あける

    print('クローリング完了')


def scraping():
    # htmlの取得
    html_files = glob.glob(html_save_dir + '*.html')

    print('スクレイピング開始')
    os.makedirs(csv_save_dir,exist_ok=True) # csv保存場所作成

    # csvにヘッダー書き込み
    file = open(csv_save_dir + 'data.csv', 'a')
    file.write('name,access,period\n')

    # 各曲htmlから抽出
    for html_dir in tqdm(html_files):
        html = open(html_dir,'r',encoding='utf-8')
        song_soup = BeautifulSoup(html, 'html.parser')
        song_name = song_soup.find('h2').string  # 曲名の取得
        song_access_num = get_access_num(song_soup)  # アクセス数の取得
        song_period = get_period(song_soup)  # 発売してからの日数を取得
        file.write('{0},{1},{2}\n'.format(song_name, song_access_num, song_period))  # csvに書き込み
        html.close()

    file.close()

    print('スクレイピング完了')


def main():
    # クローリング
    crawling()

    # スクレイピング
    scraping()


if __name__ == '__main__':
    main()

for文でtqdmというライブラリを使用しています。これを利用することで、下記のようにプログレスバーが表示されます。
クローリング、スクレイピングではfor文を回すことが多いので、めっちゃ使えると思います。

f:id:hanatasdiary:20190114155845p:plain
tqdmを使うと出てくるプログレスバー

コード書いてて躓いたところをいくつか書きます。
csvの作成

# csvにヘッダー書き込み
file = open(csv_save_dir + 'data.csv', 'a')
file.write('name,access,period\n')

追記するときは、モードを'a'にします。
書き込みはcsvなので当然カンマ区切りにしますが、文末に改行を入れる必要があります。
pythonのprint文は改行がデフォでされていたので、書き込みでも自動で改行されるのかなと思ってました…

②ローカルのhtmlをsoupへ変換

html = open(html_dir,'r',encoding='utf-8')
song_soup = BeautifulSoup(html, 'html.parser')

htmlそのものをBeautifulSoupの引数にします。requestsでgetした後にBeautifulSoupに渡すことが多かったので、若干困りました。

んで出力されたcsvがこんな感じです。

f:id:hanatasdiary:20190114063024p:plain
出力されたcsv

このcsvを利用して、考察をしてみようと思います。
考察記事はコチラ↓
まだ書けていません。