BeautifulSoup
を使って海外の歌詞サイトMetroLyricsから歌詞をスクレイピングするスクリプトを書いた。10月28日(土)に開催されるPython入門者向けハンズオン #6(#PyNyumon)でメンターをやることになっているので、その予習。
こういう感じのスクリプト(READMEと同じ内容)
MetroLyricsからランダムに歌詞を抽出して表示する.
アーティスト名を引数で指定
指定されたアーティストのMetroLyricsにある全曲を対象にする
日本語歌詞にも対応
Usage
-
$ python fetch_lyrics.py "Artist Name"
-
example
$ python fetch_lyrics.py Oasis
$ python fetch_lyrics.py Arctic Monkeys
$ python fetch_lyrics.py Aimer
作ってみて気づいたことなんかを書いていきたい。
- リダイレクトしているかどうかは
requests
では以下の方法で判断できる
>>> url = URL >>> r = requests.get(url) >>> r.history
MetroLyricsでは歌詞リストのURLは http://www.metrolyrics.com/{アーティスト名}-alpage-{ページ番号}.html
のフォーマットになっている。登録されている曲数に応じてページ数が変わるわけで、それ以上のページ番号を指定すると404
が返ってくるという予想の元で進めていた。しかし実際はhttp://www.metrolyrics.com/{アーティスト名}-lyrics.html
にリダイレクトする。リダイレクトしている場合、上記r.history
の戻り値は[<Response [302]>]
になる。リダイレクトしていない場合は空のリストが返ってくる。
- スクレイピングした結果が文字化けした場合は、
BeautifulSoup
側でデコードさせる
海外のサイトということで取得する歌詞はすべて英語であるという前提だったが、試しにAimer
やEGOIST
と入れてみた結果、歌詞リストが存在しており歌詞が取得できた。しかし日本語歌詞は文字化けを起こしていた。
requests
オブジェクトをr
としたとき、r.text
とすると文字化けが発生しやすい。このr.text
ではデコード済みのレスポンスボディをstr型で返している。r.content
でbytes型のレスポンスボディを取得してBeautifulSoupに渡すことでBeautifulSoup側でデコードしてくれる。
スクレイピングでの文字化けを防ぐ方法の詳細は以下のブログが詳しい。Pythonクローリング&スクレイピングの著者による解説なので心強い。
#PyNyumonでは特に後者で躓く受講者がいるかもしれない。そのときに解決の手助けができたら、いいなぁと思う。
実は今回の試みは、spaCyに食わせる英語テキストが欲しくて始めた。そのspaCyのチュートリアルはしばらく放置してしまっている…。