Scrapyでアニソン歌詞を収集してみる

  • 8
    いいね
  • 0
    コメント

はじめに

ScrapyというPythonのライブラリが簡単で使いやすいという噂を聞いたので早速使ってみました。

環境

安定のpyenv+anaconda(Python3)

集めたデータ

アニメソングの歌詞ならここにおまかせ?
ここの最新の追加曲ページにある7月31日から11月30日の間に追加されたアニメソングの歌詞を集めることにしました。

作成手順

インストール

pipからインストールが可能です。
$ pip install scrapy

プロジェクト作成

名前は自由に決めて大丈夫です。今回はチュートリアルの名前をそのまま採用。
$ scrapy startproject aipa_commander

中身を確認

スクレイピング初心者すぎて中身のファイルが何を意味するのか全くわからない。
とりあえずある程度使えるようになるまでは触らないようにします。

プログラム作成

僕みたいな初心者が唯一操作するディレクトリが
aipa_commander(最初に付けたプロジェクト名)/spiders/
ここにpythonのスクリプトファイルを作っていく。
いろいろ試行錯誤しながらコーディングした結果、最終的にこんな感じになった。

get_kashi.py
# -*- coding: utf-8 -*-

import scrapy

class KashiSpider(scrapy.Spider):
    name = 'kashi'

    start_urls = ['http://www.jtw.zaq.ne.jp/animesong/tuika.html']

    custom_settings = {
        "DOWNLOAD_DELAY": 1,
    }

    def parse(self, response):
        for href in response.xpath('//td[2]/a/@href'):
            full_url = response.urljoin(href.extract())
            yield scrapy.Request(full_url, callback=self.parse_item)

    def parse_item(self, response):
        kashi = response.xpath('//pre/text()').extract()
        kashi = kashi[0].split('\n')
        file = open('./歌詞/{}.txt'.format(kashi[0]), 'w')
        for j in range(len(kashi)):
            file.write(kashi[j]+'\n')
        file.close()

このたったの数行で200曲の歌詞を一度に取得できてしまうのだからScrapyは凄い。

公式のチュートリアルに載っていたコードをだいぶ参考にして作ったので、コードに関して説明することがあまりない・・・
ただ、自分がHTMLやCSSの知識がなく一番苦戦したのは
response.xpath('//td[2]/a/@href')response.xpath('//pre/text()').extract()
のような xpathの指定。

しかしそんな僕に救世主のような機能が用意されていた。
$scrapy shell "URL"
と入力すると
Shellが起動し
>>>sel.xpath('//td[2]/a/@href')
と実行すると
[<Selector xpath='//td[2]/a/@href' data='ku/qualidea/brave.html'>,
<Selector xpath='//td[2]/a/@href' data='ku/qualidea/axxxis.html'>,
<Selector xpath='//td[2]/a/@href' data='ku/qualidea/gravity.html'>,
<Selector xpath='//td[2]/a/@href' data='ku/qualidea/yakusoku.html'>,
<Selector xpath='//td[2]/a/@href' data='ku/qualidea/clever.html'>,
<Selector xpath='//td[2]/a/@href' data='to/drefes/pleasure.html'>,
・・・以下省略

このように簡単に結果を確認することができる。
Shellを使うことで自分が取りたいデータがどうやって取得できるのかをいちいちスクリプトを書き換えることなく、簡単に試すことができる。
これは本当に便利なのでスクレイピング初心者は是非活用されたし。

xpathを指定する際の記述方法については機会があれば書きますが、
今回使った
xpath(//td[2]/a/@href)
は全ての<td[2]>内の<a>内のhttpl://www~のみを取得する。
xpath('//pre/text()').extract()
は全ての<pre>内のテキスト部分のみを取得する。
という処理です。

実行結果

$ scrapy crawl kashi

と実行する(kashiの部分はnameに指定したキーワード)と
こんな感じのテキストファイルが200個生成された。
スクリーンショット 2016-12-14 0.20.23.png

テキストファイルの中身は
こんな感じ(長いので一部)
スクリーンショット 2016-12-14 0.23.52.png

おわりに

想像以上に簡単に収集できたので感動しました。
今度は画像でもやってみたいと思います。