LoginSignup
1
3

More than 5 years have passed since last update.

Webで歌詞を自動に取得

Last updated at Posted at 2019-02-18

今日、”https://mp3.zing.vn/zing-chart-tuan/bai-hat-US-UK/IWZ9Z0BW.html”で歌詞を取得する自動的なツールを書きます

技術

技術   バージョン
Nodejs 10.14.1
Puppeteer 1.12.2

準備

  1. 新たなフォルダを作る(名前はなんでも良い)
  2. 「1」で作ったフォルダにアクセスし、ターミナルでnpm init -> npm i puppeteerを書く
  3. index.jsを作る
  4. 歌詞を保存するフォルダを作る
  5. Google Chromeを使用する

Screen Shot 2019-02-18 at 8.19.47 PM.png

PuppeteerのAPI

page.evaluateだけを使用するので、他のAPIはここで参照して下さい

開発

  1. page.evaluateはWebでスクリプトを実行して、結果を帰ります。なので、HTML構築の分析が必要です。 Screen Shot 2019-02-18 at 8.52.00 PM.png

それぞれの歌は<div>の「e-item」の中に有ります:
- txt-primary _trackLinkのclassがある<a>:歌の名前
- href:歌詳細へのリンク
2. Google ChromeのConsoleでスクリプトを試します

let songs = document.getElementsByClassName('e-item');
songs = [...songs];
let array = songs.map(song => ({
    title: song.getElementsByClassName('txt-primary _trackLink')[0].innerHTML.trim(),
    url: song.getElementsByClassName('txt-primary _trackLink')[0].href
}));

結果
Screen Shot 2019-02-18 at 8.58.43 PM.png
イメージのような結果が出てくると、成功です。
3. 次は、Webで歌詞の取得スクリプトを試します
Screen Shot 2019-02-18 at 9.20.32 PM.png
歌詞はfn-wlyrics fn-contentのclassがある<p>です
また、<br />が有りますので、replaceを使って、それを省く
スクリプト: document.getElementsByClassName('fn-wlyrics fn-content')[0].innerHTML.replace(/\<br\>/g,"")
結果
Screen Shot 2019-02-18 at 9.25.33 PM.png
4. 今、index.jsを書きましょう。歌詞はファイルに保存します。

index.js
const puppeteer = require('puppeteer');
const fs = require('fs');

(async()=>{
  const browser=await puppeteer.launch({headless:true});
  const page=await browser.newPage();

  await page.goto('https://mp3.zing.vn/zing-chart-tuan/bai-hat-US-UK/IWZ9Z0BW.html');
  const songs = await page.evaluate(() => {
    let songs = document.getElementsByClassName('e-item');
    songs = [...songs];
    let array = songs.map(song => ({
        title: song.getElementsByClassName('txt-primary _trackLink')[0].innerHTML.trim(),
        url: song.getElementsByClassName('txt-primary _trackLink')[0].href
    }));
    return array;
  });

  for(let song of songs){
    await page.goto(song.url);
    let lyric = await page.evaluate(()=>{
      const evaluatedLyric = document.getElementsByClassName('fn-wlyrics fn-content')[0];
      // 歌詞はいつもあるわけではないので、条件をチェック
      if (evaluatedLyric !== undefined) {
        return evaluatedLyric.innerHTML.replace(/\<br\>/g,"");
      } else return "歌詞無し";
    });
    await fs.writeFile(`songs/${song.title}.txt`,lyric,function(err){
      if(err) throw err;
      console.log("取得: "+song.title);
    });
  }
  await browser.close();
})();

最終的に、以下の結果が出る
Screen Shot 2019-02-18 at 9.39.20 PM.png
Screen Shot 2019-02-18 at 9.40.51 PM.png
Screen Shot 2019-02-18 at 9.42.29 PM.png

まとめ

この方法はかなり簡単ですが、HTML構築の分析が必要なので、時々嫌を感じるかもしれません。それで、使用の前に、注意しべきです。

1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3