今日、”https://mp3.zing.vn/zing-chart-tuan/bai-hat-US-UK/IWZ9Z0BW.html”で歌詞を取得する自動的なツールを書きます
#技術
技術 | バージョン |
---|---|
Nodejs | 10.14.1 |
Puppeteer | 1.12.2 |
#準備
- 新たなフォルダを作る(名前はなんでも良い)
- 「1」で作ったフォルダにアクセスし、ターミナルで
npm init
->npm i puppeteer
を書く - index.jsを作る
- 歌詞を保存するフォルダを作る
- Google Chromeを使用する
#PuppeteerのAPI
page.evaluateだけを使用するので、他のAPIはここで参照して下さい
#開発
- page.evaluateはWebでスクリプトを実行して、結果を帰ります。なので、HTML構築の分析が必要です。
それぞれの歌は<div>の「e-item」の中に有ります:
- txt-primary _trackLinkのclassがある<a>:歌の名前
- href:歌詳細へのリンク
- 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
}));
結果
イメージのような結果が出てくると、成功です。
3. 次は、Webで歌詞の取得スクリプトを試します
歌詞はfn-wlyrics fn-contentのclassがある<p>です
また、<br />が有りますので、replaceを使って、それを省く
スクリプト: document.getElementsByClassName('fn-wlyrics fn-content')[0].innerHTML.replace(/\<br\>/g,"")
結果
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();
})();
#まとめ
この方法はかなり簡単ですが、HTML構築の分析が必要なので、時々嫌を感じるかもしれません。それで、使用の前に、注意しべきです。