Slackのボットと様々なWebAPIを組み合わせて、Slack上から情報を得られるのは非常に便利です。
しかし、サービスによってはWebAPIがなくCookie認証が必要な場合があります。
そういったサービスにPuppetteerを使ってログインしてスクレイピングする方法について説明します。
細かい説明は省きますので、以下のサンプルコードを確認してください。
ログインしてCookieを取得する
まずはIDとパスワードを使ってログインしてCookieを取得します。
ここはログインするページに沿って適切に入力出来るように調節してください。
const browser = await puppeteer.launch({headless: true});
const page = await browser.newPage();
// パスワードを使ってログイン
await page.goto(LOGIN_URL, {waitUntil: 'domcontentloaded'});
// サービスによって異なるので、ご自身で調べてください
// ここでは一般的によくありそうな場合で実装しています
await page.type('input[name="user[email]"]', ACCOUNT_EMAIL);
await page.type('input[name="user[password]"]', ACCOUNT_PASS);
page.click('input[name="commit"]');
await page.waitForNavigation({timeout: 60000, waitUntil: 'domcontentloaded'});
ログインが完了したら、Cookieを取得してすべてjsonに変換してファイルに保存しましょう。
// Cookieをローカルに保存
const afterCookies = await page.cookies();
fs.writeFileSync(COOKIES_PATH, JSON.stringify(afterCookies));
これでCookieが取得出来ました。
Cookieを利用してスクレイピングを行う
先ほど保存したCookieのファイルを利用して、ログインしてそのページの #title
という要素の中の文字を取得しようと思います。
まずは先ほどjsonで保存したCookieを読み込みます。
// ローカルのCookieを使ってログイン
const cookies = JSON.parse(fs.readFileSync(COOKIES_PATH, 'utf-8'));
for (let cookie of cookies) {
await page.setCookie(cookie);
}
Cookieにログイン情報がのってるので問題なくログイン出来ると思います。
あとは普通にスクレイピングすればOKです。
// 例えばタイトルを取得
await page.goto(url, {waitUntil: 'domcontentloaded'});
let title = await page.$eval('#title', item => {
return item.textContent;
});
注意
当たり前ですが、スクレイピングする際は利用サイトの負荷をかけることになります。
なので、利用サービスの迷惑にならないように注意してください。
また、WebAPIが用意されているならそちらを利用した方がいいです。
サービスの方で適切に管理されているので安全に利用できます。